This is an archive of the discontinued LLVM Phabricator instance.

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

Authored by bkelley on Mar 15 2017, 3:25 PM.

Details

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.

Diff Detail

Event Timeline

bkelley created this revision.Mar 15 2017, 3:25 PM
rjmccall added inline comments.Mar 16 2017, 9:33 AM
lib/AST/DeclCXX.cpp
726

Similarly, I think the best way of expressing this is to re-arrange the blocks like so:

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
  //   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 (!Context.getLangOpts().ObjCAutoRefCount) {
  setHasObjectMember(true);
}
lib/Sema/SemaDeclCXX.cpp
4407

I think this entire check can just be:

if (FieldBaseElementType.hasNonTrivialObjCLifetime())

The language-options checks are almost certainly slower than just checking the qualifiers.

bkelley marked 2 inline comments as done.Mar 17 2017, 3:56 PM
bkelley added inline comments.
lib/Sema/SemaDeclCXX.cpp
4407

I see. handleObjCOwnershipTypeAttr() in SemaType.cpp only adds OCL_Weak or OCL_ExplicitNone outside of ARC and it's a compile error to use __weak without -fobjc-arc or -fobjc-weak, so hasNonTrivialObjCLifetime() is indeed much more simple. Thanks!

bkelley updated this revision to Diff 92216.Mar 17 2017, 3:57 PM
bkelley marked an inline comment as done.

Integrated feedback from @rjmccall

rjmccall edited edge metadata.Mar 20 2017, 10:58 PM

Thanks, LGTM.

rjmccall accepted this revision.Mar 20 2017, 10:58 PM
This revision is now accepted and ready to land.Mar 20 2017, 10:58 PM

Thank you @rjmccall for the approval. I don't have commit access; would someone be willing to commit this path for me please? Thanks!

Thank you @rjmccall for the approval. I don't have commit access; would someone be willing to commit this path for me please? Thanks!

You have a lot of patches here. :) I would encourage you to just ask for commit access; it's not a strenuous process. http://llvm.org/docs/DeveloperPolicy.html

John.

bkelley closed this revision.Mar 29 2017, 10:44 AM