bkelley created this revision. -Warc-repeated-use-of-weak should produce the same warnings with -fobjc-weak as it does with -objc-arc. Also check for ObjCWeak along with ObjCAutoRefCount when recording the use of an evaluated weak variable. Add a -fobjc-weak run to the existing arc-repeated-weak test case and adapt it slightly to work in both modes.
https://reviews.llvm.org/D31005 Files: lib/Sema/SemaDecl.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprMember.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaPseudoObject.cpp test/SemaObjC/arc-repeated-weak.mm
Index: test/SemaObjC/arc-repeated-weak.mm =================================================================== --- test/SemaObjC/arc-repeated-weak.mm +++ test/SemaObjC/arc-repeated-weak.mm @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s +// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s @interface Test { @public @@ -445,8 +446,8 @@ @class NSString; @interface NSBundle +(NSBundle *)foo; -@property (class) NSBundle *foo2; -@property NSString *prop; +@property (class, strong) NSBundle *foo2; +@property (strong) NSString *prop; @property(weak) NSString *weakProp; @end @@ -463,6 +464,8 @@ use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}} } +// With -fobjc-weak, the cast below is allowed. +#if __has_feature(objc_arc) // This used to crash in the constructor of WeakObjectProfileTy when a // DeclRefExpr was passed that didn't reference a VarDecl. @@ -475,3 +478,4 @@ void foo1() { INTFPtrTy tmp = (INTFPtrTy)e1; // expected-error{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}} } +#endif Index: lib/Sema/SemaPseudoObject.cpp =================================================================== --- lib/Sema/SemaPseudoObject.cpp +++ lib/Sema/SemaPseudoObject.cpp @@ -841,7 +841,7 @@ result = S.ImpCastExprToType(result.get(), propType, CK_BitCast); } } - if (S.getLangOpts().ObjCAutoRefCount) { + if (S.getLangOpts().ObjCAutoRefCount || S.getLangOpts().ObjCWeak) { Qualifiers::ObjCLifetime LT = propType.getObjCLifetime(); if (LT == Qualifiers::OCL_Weak) if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation())) @@ -962,11 +962,12 @@ } ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) { - if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty() && + if ((S.getLangOpts().ObjCAutoRefCount || S.getLangOpts().ObjCWeak) && + isWeakProperty() && !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, SyntacticForm->getLocStart())) - S.recordUseOfEvaluatedWeak(SyntacticRefExpr, - SyntacticRefExpr->isMessagingGetter()); + S.recordUseOfEvaluatedWeak(SyntacticRefExpr, + SyntacticRefExpr->isMessagingGetter()); return PseudoOpBuilder::complete(SyntacticForm); } Index: lib/Sema/SemaExprObjC.cpp =================================================================== --- lib/Sema/SemaExprObjC.cpp +++ lib/Sema/SemaExprObjC.cpp @@ -3100,7 +3100,9 @@ // In ARC, check for message sends which are likely to introduce // retain cycles. checkRetainCycles(Result); + } + if (getLangOpts().ObjCAutoRefCount || getLangOpts().ObjCWeak) { if (!isImplicit && Method) { if (const ObjCPropertyDecl *Prop = Method->findPropertyDecl()) { bool IsWeak = Index: lib/Sema/SemaExprMember.cpp =================================================================== --- lib/Sema/SemaExprMember.cpp +++ lib/Sema/SemaExprMember.cpp @@ -1475,7 +1475,7 @@ } } bool warn = true; - if (S.getLangOpts().ObjCAutoRefCount) { + if (S.getLangOpts().ObjCAutoRefCount || S.getLangOpts().ObjCWeak) { Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts(); if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp)) if (UO->getOpcode() == UO_Deref) @@ -1502,7 +1502,7 @@ IV, IV->getUsageType(BaseType), MemberLoc, OpLoc, BaseExpr.get(), IsArrow); - if (S.getLangOpts().ObjCAutoRefCount) { + if (S.getLangOpts().ObjCAutoRefCount || S.getLangOpts().ObjCWeak) { if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc)) S.recordUseOfEvaluatedWeak(Result); Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -704,7 +704,7 @@ // Loading a __weak object implicitly retains the value, so we need a cleanup to // balance that. - if (getLangOpts().ObjCAutoRefCount && + if ((getLangOpts().ObjCAutoRefCount || getLangOpts().ObjCWeak) && E->getType().getObjCLifetime() == Qualifiers::OCL_Weak) Cleanup.setExprNeedsCleanups(true); @@ -2509,11 +2509,13 @@ ObjCIvarRefExpr(IV, IV->getUsageType(SelfExpr.get()->getType()), Loc, IV->getLocation(), SelfExpr.get(), true, true); - if (getLangOpts().ObjCAutoRefCount) { + if (getLangOpts().ObjCAutoRefCount || getLangOpts().ObjCWeak) { if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc)) recordUseOfEvaluatedWeak(Result); } + } + if (getLangOpts().ObjCAutoRefCount) { if (CurContext->isClosure()) Diag(Loc, diag::warn_implicitly_retains_self) << FixItHint::CreateInsertion(Loc, "self->"); @@ -10317,19 +10319,25 @@ const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(InnerLHS); if (!DRE || DRE->getDecl()->hasAttr<BlocksAttr>()) checkRetainCycles(LHSExpr, RHS.get()); + } + if (LHSType.getObjCLifetime() == Qualifiers::OCL_Strong || + (!getLangOpts().ObjCAutoRefCount && getLangOpts().ObjCWeak && + LHSType.getObjCLifetime() != Qualifiers::OCL_Weak)) { // It is safe to assign a weak reference into a strong variable. // Although this code can still have problems: // id x = self.weakProp; // id y = self.weakProp; // we do not warn to warn spuriously when 'x' and 'y' are on separate // paths through the function. This should be revisited if // -Wrepeated-use-of-weak is made flow-sensitive. + // For ObjCWeak only, we do not warn if the assign is to a non-weak + // variable, which will be valid for the current autorelease scope. if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RHS.get()->getLocStart())) getCurFunction()->markSafeWeakUse(RHS.get()); - } else if (getLangOpts().ObjCAutoRefCount) { + } else if (getLangOpts().ObjCAutoRefCount || getLangOpts().ObjCWeak) { checkUnsafeExprAssigns(Loc, LHSExpr, RHS.get()); } } Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -10179,7 +10179,9 @@ // we do not warn to warn spuriously when 'x' and 'y' are on separate // paths through the function. This should be revisited if // -Wrepeated-use-of-weak is made flow-sensitive. - if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong && + if ((VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong || + (!getLangOpts().ObjCAutoRefCount && getLangOpts().ObjCWeak && + VDecl->getType().getObjCLifetime() != Qualifiers::OCL_Weak)) && !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Init->getLocStart())) getCurFunction()->markSafeWeakUse(Init);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits