Index: lib/Sema/SemaCast.cpp =================================================================== --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -872,7 +872,7 @@ } SrcExpr = ExprError(); } else if (tcr == TC_Success) { - if (Self.getLangOpts().ObjCAutoRefCount) + if (Self.getLangOpts().ObjCAutoRefCount || Self.getLangOpts().ObjCWeak) checkObjCConversion(Sema::CCK_OtherCast); DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange); } @@ -936,7 +936,7 @@ } else if (tcr == TC_Success) { if (Kind == CK_BitCast) checkCastAlign(); - if (Self.getLangOpts().ObjCAutoRefCount) + if (Self.getLangOpts().ObjCAutoRefCount || Self.getLangOpts().ObjCWeak) checkObjCConversion(Sema::CCK_OtherCast); } else if (Kind == CK_BitCast) { checkCastAlign(); Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -14493,7 +14493,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); @@ -14628,16 +14628,20 @@ << FixItHint::CreateInsertion(FD->getLocation(), "*"); QualType T = Context.getObjCObjectPointerType(FD->getType()); FD->setType(T); - } else if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported && + } else if ((getLangOpts().ObjCAutoRefCount || getLangOpts().ObjCWeak) && + 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 (lifetime && + ((getLangOpts().ObjCAutoRefCount && + lifetime != Qualifiers::OCL_ExplicitNone) || + (getLangOpts().ObjCWeak && lifetime == Qualifiers::OCL_Weak))) { SourceLocation loc = FD->getLocation(); if (getSourceManager().isInSystemHeader(loc)) { if (!FD->hasAttr()) { @@ -14648,7 +14652,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 @@ -7150,8 +7150,10 @@ // [...] 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 ((S.getLangOpts().ObjCAutoRefCount && + FieldType.hasNonTrivialObjCLifetime()) || + (S.getLangOpts().ObjCWeak && + FieldType.getObjCLifetime() == Qualifiers::OCL_Weak)) { 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 @@ -6680,6 +6680,8 @@ // full-expression's cleanups. if ((S.getLangOpts().ObjCAutoRefCount && MTE->getType()->isObjCLifetimeType()) || + (S.getLangOpts().ObjCWeak && + MTE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) || (MTE->getStorageDuration() == SD_Automatic && MTE->getType().isDestructedType())) S.Cleanup.setExprNeedsCleanups(true); 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}} +}