commit 09f1bed2925614122af7ed92439bf78bb5c0ac44
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. It turns out the reason we delayed setting this until
    completeDefinition() was for a warning that has since been removed as
    part of -Warc-abi, so we just do it eagerly now.

diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index e0801fb..37bd050 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -677,17 +677,24 @@ void CXXRecordDecl::addedMember(Decl *D) {
     //
     // Automatic Reference Counting: the presence of a member of Objective-C pointer type
     // that does not explicitly have no lifetime makes the class a non-POD.
-    // However, we delay setting PlainOldData to false in this case so that
-    // Sema has a chance to diagnostic causes where the same class will be
-    // non-POD with Automatic Reference Counting but a POD without ARC.
-    // In this case, the class will become a non-POD class when we complete
-    // the definition.
     ASTContext &Context = getASTContext();
     QualType T = Context.getBaseElementType(Field->getType());
     if (T->isObjCRetainableType() || T.isObjCGCStrong()) {
-      if (!Context.getLangOpts().ObjCAutoRefCount ||
-          T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone)
+      if (!Context.getLangOpts().ObjCAutoRefCount) {
         setHasObjectMember(true);
+      } else if (T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone) {
+        // Objective-C Automatic Reference Counting:
+        //   If a class has a non-static data member of Objective-C pointer
+        //   type (or array thereof), it is a non-POD type and its
+        //   default constructor (if any), copy constructor, move constructor,
+        //   copy assignment operator, move assignment operator, and destructor are
+        //   non-trivial.
+        setHasObjectMember(true);
+        struct DefinitionData &Data = data();
+        Data.PlainOldData = false;
+        Data.HasTrivialSpecialMembers = 0;
+        Data.HasIrrelevantDestructor = false;
+      }
     } else if (!T.isCXX98PODType(Context))
       data().PlainOldData = false;
     
@@ -1277,19 +1284,6 @@ void CXXRecordDecl::completeDefinition() {
 void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
   RecordDecl::completeDefinition();
   
-  if (hasObjectMember() && getASTContext().getLangOpts().ObjCAutoRefCount) {
-    // Objective-C Automatic Reference Counting:
-    //   If a class has a non-static data member of Objective-C pointer
-    //   type (or array thereof), it is a non-POD type and its
-    //   default constructor (if any), copy constructor, move constructor,
-    //   copy assignment operator, move assignment operator, and destructor are
-    //   non-trivial.
-    struct DefinitionData &Data = data();
-    Data.PlainOldData = false;
-    Data.HasTrivialSpecialMembers = 0;
-    Data.HasIrrelevantDestructor = false;
-  }
-  
   // If the class may be abstract (but hasn't been marked as such), check for
   // any pure final overriders.
   if (mayBeAbstract()) {
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)
