diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index d9d7f0a..5223a8f 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1107,7 +1107,7 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
     return false;
 
   // Types of valid local variables should be complete, so this should succeed.
-  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
 
     // White-list anything with an __attribute__((unused)) type.
     QualType Ty = VD->getType();
@@ -1129,11 +1129,20 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
         return false;
 
       if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Tag)) {
+        if (!RD->hasTrivialDestructor())
+          return false;
+
         // FIXME: Checking for the presence of a user-declared constructor
         // isn't completely accurate; we'd prefer to check that the initializer
         // has no side effects.
-        if (RD->hasUserDeclaredConstructor() || !RD->hasTrivialDestructor())
-          return false;
+        if (RD->hasUserDeclaredConstructor()) {
+          if (const Expr *Init = VD->getInit()) {
+            const CXXConstructExpr *Construct =
+              dyn_cast<CXXConstructExpr>(Init);
+            if (Construct && !Construct->isElidable())
+              return false;
+          }
+        }
       }
     }
 
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index c3a5994..ec037cb 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -41,6 +41,7 @@ class A {
     A(int x) {}
     A(int *x) {}
     A(A *a) {}
+    ~A();
 };
 
 A getA() { return A(); }
diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp
index 5ba1f2a..294abf8 100644
--- a/test/SemaCXX/warn-unused-variables.cpp
+++ b/test/SemaCXX/warn-unused-variables.cpp
@@ -80,3 +80,13 @@ namespace PR10168 {
     f<char>(); // expected-note {{here}}
   }
 }
+
+namespace PR11550 {
+  struct S {
+    S();
+  };
+  S foo();
+  void bar() {
+    S x = foo(); // expected-warning {{unused variable 'x'}}
+  }
+}
