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/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -14492,7 +14492,7 @@ // Verify that all the fields are okay. SmallVector RecFields; - bool ARCErrReported = false; + bool ObjCFieldLifetimeErrReported = false; for (ArrayRef::iterator i = Fields.begin(), end = Fields.end(); i != end; ++i) { FieldDecl *FD = cast(*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()) { @@ -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/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/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6674,14 +6674,10 @@ /*IsInitializerList=*/false, ExtendingEntity->getDecl()); - // If we're binding to an Objective-C object that has lifetime, we - // 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()) || - (MTE->getStorageDuration() == SD_Automatic && - MTE->getType().isDestructedType())) + // If we're extending this temporary to automatic storage duration -- we + // need to register its cleanup during the full-expression's cleanups. + if (MTE->getStorageDuration() == SD_Automatic && + MTE->getType().isDestructedType()) S.Cleanup.setExprNeedsCleanups(true); CurInit = MTE; 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}} +}