From: Fariborz Jahanian Date: Tue, 17 Jan 2012 22:58:16 +0000 (+0000) Subject: objc-arc: when 'assign' attribute is unspecified, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=87eaf726528124a1ad49f38402e9b619685fe30b;p=clang objc-arc: when 'assign' attribute is unspecified, rely on property's type for its life-time to avoid bogus warning with -Warc-unsafe-retained-assign. // rdar://10694932 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148355 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index f6538492cd..06525a42e4 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -4652,7 +4652,19 @@ bool Sema::checkUnsafeAssigns(SourceLocation Loc, void Sema::checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS) { - QualType LHSType = LHS->getType(); + QualType LHSType; + // PropertyRef on LHS type need be directly obtained from + // its declaration as it has a PsuedoType. + ObjCPropertyRefExpr *PRE + = dyn_cast(LHS->IgnoreParens()); + if (PRE && !PRE->isImplicitProperty()) { + const ObjCPropertyDecl *PD = PRE->getExplicitProperty(); + if (PD) + LHSType = PD->getType(); + } + + if (LHSType.isNull()) + LHSType = LHS->getType(); if (checkUnsafeAssigns(Loc, LHSType, RHS)) return; Qualifiers::ObjCLifetime LT = LHSType.getObjCLifetime(); @@ -4660,8 +4672,7 @@ void Sema::checkUnsafeExprAssigns(SourceLocation Loc, if (LT != Qualifiers::OCL_None) return; - if (ObjCPropertyRefExpr *PRE - = dyn_cast(LHS->IgnoreParens())) { + if (PRE) { if (PRE->isImplicitProperty()) return; const ObjCPropertyDecl *PD = PRE->getExplicitProperty(); @@ -4669,7 +4680,15 @@ void Sema::checkUnsafeExprAssigns(SourceLocation Loc, return; unsigned Attributes = PD->getPropertyAttributes(); - if (Attributes & ObjCPropertyDecl::OBJC_PR_assign) + if (Attributes & ObjCPropertyDecl::OBJC_PR_assign) { + // when 'assign' attribute was not explicitly specified + // by user, ignore it and rely on property type itself + // for lifetime info. + unsigned AsWrittenAttr = PD->getPropertyAttributesAsWritten(); + if (!(AsWrittenAttr & ObjCPropertyDecl::OBJC_PR_assign) && + LHSType->isObjCRetainableType()) + return; + while (ImplicitCastExpr *cast = dyn_cast(RHS)) { if (cast->getCastKind() == CK_ARCConsumeObject) { Diag(Loc, diag::warn_arc_retained_property_assign) @@ -4678,5 +4697,6 @@ void Sema::checkUnsafeExprAssigns(SourceLocation Loc, } RHS = cast->getSubExpr(); } + } } } diff --git a/test/SemaObjC/arc-property-lifetime.m b/test/SemaObjC/arc-property-lifetime.m index 2c27a518dd..3fd845bd9e 100644 --- a/test/SemaObjC/arc-property-lifetime.m +++ b/test/SemaObjC/arc-property-lifetime.m @@ -149,3 +149,22 @@ } @end +// rdar://10694932 +@interface Baz +@property id prop; +@property __strong id strong_prop; +@property (strong) id strong_attr_prop; +@property (strong) __strong id realy_strong_attr_prop; ++ (id) alloc; +- (id) init; +- (id) implicit; +- (void) setImplicit : (id) arg; +@end + +void foo(Baz *f) { + f.prop = [[Baz alloc] init]; + f.strong_prop = [[Baz alloc] init]; + f.strong_attr_prop = [[Baz alloc] init]; + f.realy_strong_attr_prop = [[Baz alloc] init]; + f.implicit = [[Baz alloc] init]; +}