Improvements to the uninitialized variable warning: Check if the constructor
call is elidable or if the constructor is trivial instead of checking if it
is user declared.

llvm-svn: 147652
diff --git a/clang/test/SemaCXX/uninitialized.cpp b/clang/test/SemaCXX/uninitialized.cpp
index c3a5994..ec037cb 100644
--- a/clang/test/SemaCXX/uninitialized.cpp
+++ b/clang/test/SemaCXX/uninitialized.cpp
@@ -41,6 +41,7 @@
     A(int x) {}
     A(int *x) {}
     A(A *a) {}
+    ~A();
 };
 
 A getA() { return A(); }
diff --git a/clang/test/SemaCXX/warn-unused-variables.cpp b/clang/test/SemaCXX/warn-unused-variables.cpp
index 5ba1f2a..5827019 100644
--- a/clang/test/SemaCXX/warn-unused-variables.cpp
+++ b/clang/test/SemaCXX/warn-unused-variables.cpp
@@ -80,3 +80,45 @@
     f<char>(); // expected-note {{here}}
   }
 }
+
+namespace PR11550 {
+  struct S1 {
+    S1();
+  };
+  S1 makeS1();
+  void testS1(S1 a) {
+    // This constructor call can be elided.
+    S1 x = makeS1(); // expected-warning {{unused variable 'x'}}
+
+    // This one cannot, so no warning.
+    S1 y;
+
+    // This call cannot, but the constructor is trivial.
+    S1 z = a; // expected-warning {{unused variable 'z'}}
+  }
+
+  // The same is true even when we know thet constructor has side effects.
+  void foo();
+  struct S2 {
+    S2() {
+      foo();
+    }
+  };
+  S2 makeS2();
+  void testS2(S2 a) {
+    S2 x = makeS2(); // expected-warning {{unused variable 'x'}}
+    S2 y;
+    S2 z = a; // expected-warning {{unused variable 'z'}}
+  }
+
+  // Or when the constructor is not declared by the user.
+  struct S3 {
+    S1 m;
+  };
+  S3 makeS3();
+  void testS3(S3 a) {
+    S3 x = makeS3(); // expected-warning {{unused variable 'x'}}
+    S3 y;
+    S3 z = a; // expected-warning {{unused variable 'z'}}
+  }
+}