[Objective-C] C++ Classes with __weak Members non-POD Types when using -fobjc-weak

Summary: When adding an Objective-C retainable type member to a C++ class, also check the LangOpts.ObjCWeak flag and the lifetime qualifier so __weak qualified Objective-C pointer members cause the class to be a non-POD type with non-trivial special members, so the compiler always emits the necessary runtime calls for copying, moving, and destroying the weak member. Otherwise, Objective-C++ classes with weak Objective-C pointer members compiled with -fobjc-weak exhibit undefined behavior if the C++ class is classified as a POD type.

Reviewers: rsmith, benlangmuir, doug.gregor, rjmccall

Reviewed By: rjmccall

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D31003

llvm-svn: 299008
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 7418370..a1aed33 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -722,9 +722,7 @@
     ASTContext &Context = getASTContext();
     QualType T = Context.getBaseElementType(Field->getType());
     if (T->isObjCRetainableType() || T.isObjCGCStrong()) {
-      if (!Context.getLangOpts().ObjCAutoRefCount) {
-        setHasObjectMember(true);
-      } else if (T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone) {
+      if (T.hasNonTrivialObjCLifetime()) {
         // 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
@@ -736,6 +734,8 @@
         Data.PlainOldData = false;
         Data.HasTrivialSpecialMembers = 0;
         Data.HasIrrelevantDestructor = false;
+      } else if (!Context.getLangOpts().ObjCAutoRefCount) {
+        setHasObjectMember(true);
       }
     } else if (!T.isCXX98PODType(Context))
       data().PlainOldData = false;