commit d0f170a285ffb39819ee99ee82c4641e869e6260
Author: Ben Langmuir <blangmuir@apple.com>
Date:   Mon Sep 15 09:39:43 2014 -0700

    Fix an assertion failure trying to emit a trivial destructor in ObjC++
    
    If a base class declares a destructor, we will add the implicit
    destructor for the subclass in
    ActOnFields -> AddImplicitlyDeclaredMembersToClass
    
    But in Objective C++, we did not compute whether we have a trivial
    destructor until after that in
    CXXRecordDecl::completeDefinition()
    
    This was leading to a mismatch between the class, which thought it had
    no trivial destructor, and the CXXDestructorDecl, which considered
    itself trivial.

diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 006a3c4..01f3b0e 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -8992,9 +8992,10 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
 
   AddOverriddenMethods(ClassDecl, Destructor);
 
-  // We don't need to use SpecialMemberIsTrivial here; triviality for
-  // destructors is easy to compute.
-  Destructor->setTrivial(ClassDecl->hasTrivialDestructor());
+  Destructor->setTrivial(
+      ClassDecl->needsOverloadResolutionForDestructor()
+        ? SpecialMemberIsTrivial(Destructor, CXXDestructor)
+        : ClassDecl->hasTrivialDestructor());
 
   if (ShouldDeleteSpecialMember(Destructor, CXXDestructor))
     SetDeclDeleted(Destructor, ClassLoc);
diff --git a/test/CodeGenObjCXX/destroy.mm b/test/CodeGenObjCXX/destroy.mm
new file mode 100644
index 0000000..c53ac39
--- /dev/null
+++ b/test/CodeGenObjCXX/destroy.mm
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -disable-llvm-optzns -o - %s | FileCheck %s
+// rdar://18249673
+
+@class MyObject;
+struct base {
+  ~base() = default;
+};
+struct derived : public base {
+  MyObject *myobject;
+};
+
+void test1() {
+  derived d1;
+}
+// CHECK-LABEL: define void @_Z5test1v()
+// CHECK: call void @_ZN7derivedC1Ev
+// CHECK: call void @_ZN7derivedD1Ev
+
+void test2() {
+  derived *d2 = new derived;
+  delete d2;
+}
+// CHECK-LABEL: define void @_Z5test2v()
+// CHECK:   call void @_ZN7derivedC1Ev
+// CHECK:   call void @_ZN7derivedD1Ev
+
+template <typename T>
+struct tderived : public base {
+  MyObject *myobject;
+};
+void test3() {
+  tderived<int> d1;
+}
+// CHECK-LABEL: define void @_Z5test3v()
+// CHECK: call void @_ZN8tderivedIiEC1Ev
+// CHECK: call void @_ZN8tderivedIiED1Ev
+
+void test4() {
+  tderived<int> *d2 = new tderived<int>;
+  delete d2;
+}
+// CHECK-LABEL: define void @_Z5test4v()
+// CHECK: call void @_ZN8tderivedIiEC1Ev
+// CHECK: call void @_ZN8tderivedIiED1Ev
+
+// CHECK-LABEL: define linkonce_odr void @_ZN8tderivedIiED2Ev
+// CHECK: call void @objc_storeStrong(i8** {{.*}}, i8* null)
+
+// CHECK-LABEL: define linkonce_odr void @_ZN7derivedD2Ev
+// CHECK: call void @objc_storeStrong(i8** {{.*}}, i8* null)
