bkelley updated this revision to Diff 92220. bkelley added a comment. Integrated feedback from @rjmccall
https://reviews.llvm.org/D31007 Files: include/clang/AST/Type.h lib/AST/Type.cpp lib/Sema/SemaCast.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaInit.cpp test/SemaObjCXX/objc-weak.mm
Index: test/SemaObjCXX/objc-weak.mm =================================================================== --- /dev/null +++ test/SemaObjCXX/objc-weak.mm @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++98 -Wno-c++0x-extensions -verify %s + +@interface AnObject +@property(weak) id value; +@end + +__attribute__((objc_arc_weak_reference_unavailable)) +@interface NOWEAK : AnObject // expected-note 2 {{class is declared here}} +@end + +struct S { + __weak id a; // expected-note {{because type 'S' has a member with __weak ownership}} +}; + +union U { + __weak id a; // expected-error {{ARC forbids Objective-C objects in union}} + S b; // expected-error {{union member 'b' has a non-trivial copy constructor}} +}; + +void testCast(AnObject *o) { + __weak id a = reinterpret_cast<__weak NOWEAK *>(o); // expected-error {{class is incompatible with __weak references}} \ + // expected-error {{explicit ownership qualifier on cast result has no effect}} \ + // expected-error {{assignment of a weak-unavailable object to a __weak object}} + + __weak id b = static_cast<__weak NOWEAK *>(o); // expected-error {{class is incompatible with __weak references}} \ + // expected-error {{explicit ownership qualifier on cast result has no effect}} \ + // expected-error {{assignment of a weak-unavailable object to a __weak object}} +} Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6678,8 +6678,7 @@ // need cleanups. Likewise if we're extending this temporary to automatic // storage duration -- we need to register its cleanup during the // full-expression's cleanups. - if ((S.getLangOpts().ObjCAutoRefCount && - MTE->getType()->isObjCLifetimeType()) || + if (MTE->getType()->isNonTrivialObjCLifetimeType() || (MTE->getStorageDuration() == SD_Automatic && MTE->getType().isDestructedType())) S.Cleanup.setExprNeedsCleanups(true); Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -7145,8 +7145,7 @@ // [...] nontrivally ownership-qualified types are [...] not trivially // default constructible, copy constructible, move constructible, copy // assignable, move assignable, or destructible [...] - if (S.getLangOpts().ObjCAutoRefCount && - FieldType.hasNonTrivialObjCLifetime()) { + if (FieldType.hasNonTrivialObjCLifetime()) { if (Diagnose) S.Diag(FI->getLocation(), diag::note_nontrivial_objc_ownership) << RD << FieldType.getObjCLifetime(); Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -14492,7 +14492,7 @@ // Verify that all the fields are okay. SmallVector<FieldDecl*, 32> RecFields; - bool ARCErrReported = false; + bool ObjCFieldLifetimeErrReported = false; for (ArrayRef<Decl *>::iterator i = Fields.begin(), end = Fields.end(); i != end; ++i) { FieldDecl *FD = cast<FieldDecl>(*i); @@ -14627,16 +14627,16 @@ << FixItHint::CreateInsertion(FD->getLocation(), "*"); QualType T = Context.getObjCObjectPointerType(FD->getType()); FD->setType(T); - } else if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported && + } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && + Record && !ObjCFieldLifetimeErrReported && (!getLangOpts().CPlusPlus || Record->isUnion())) { - // It's an error in ARC if a field has lifetime. + // It's an error in ARC or Weak if a field has lifetime. // We don't want to report this in a system header, though, // so we just make the field unavailable. // FIXME: that's really not sufficient; we need to make the type // itself invalid to, say, initialize or copy. QualType T = FD->getType(); - Qualifiers::ObjCLifetime lifetime = T.getObjCLifetime(); - if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone) { + if (T.hasNonTrivialObjCLifetime()) { SourceLocation loc = FD->getLocation(); if (getSourceManager().isInSystemHeader(loc)) { if (!FD->hasAttr<UnavailableAttr>()) { @@ -14647,7 +14647,7 @@ Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag) << T->isBlockPointerType() << Record->getTagKind(); } - ARCErrReported = true; + ObjCFieldLifetimeErrReported = true; } } else if (getLangOpts().ObjC1 && getLangOpts().getGC() != LangOptions::NonGC && Index: lib/Sema/SemaCast.cpp =================================================================== --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -871,7 +871,7 @@ } SrcExpr = ExprError(); } else if (tcr == TC_Success) { - if (Self.getLangOpts().ObjCAutoRefCount) + if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) checkObjCConversion(Sema::CCK_OtherCast); DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange); } @@ -935,7 +935,7 @@ } else if (tcr == TC_Success) { if (Kind == CK_BitCast) checkCastAlign(); - if (Self.getLangOpts().ObjCAutoRefCount) + if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) checkObjCConversion(Sema::CCK_OtherCast); } else if (Kind == CK_BitCast) { checkCastAlign(); Index: lib/AST/Type.cpp =================================================================== --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -3768,6 +3768,12 @@ return type->isObjCRetainableType(); } +/// Returns true if objects of this type are qualified with non-trivial +/// lifetime semantics. +bool Type::isNonTrivialObjCLifetimeType() const { + return CanonicalType.hasNonTrivialObjCLifetime(); +} + /// \brief Determine whether the given type T is a "bridgable" Objective-C type, /// which is either an Objective-C object pointer type or an bool Type::isObjCARCBridgableType() const { Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -1694,6 +1694,7 @@ bool isObjCObjectPointerType() const; // pointer to ObjC object bool isObjCRetainableType() const; // ObjC object or block pointer bool isObjCLifetimeType() const; // (array of)* retainable type + bool isNonTrivialObjCLifetimeType() const; bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type bool isObjCNSObjectType() const; // __attribute__((NSObject)) bool isObjCIndependentClassType() const; // __attribute__((objc_independent_class))
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits