Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit f884a84

Browse files
committed
[Objective-C] Fix "repeated use of weak" warning with -fobjc-weak
Summary: -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. Reviewers: rsmith, doug.gregor, jordan_rose, rjmccall Reviewed By: rjmccall Subscribers: arphaman, rjmccall, cfe-commits Differential Revision: https://reviews.llvm.org/D31005 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@299011 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 16b7f51 commit f884a84

File tree

8 files changed

+41
-27
lines changed

8 files changed

+41
-27
lines changed

Diff for: include/clang/AST/Type.h

+3
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,9 @@ class QualType {
10201020
return getQualifiers().hasStrongOrWeakObjCLifetime();
10211021
}
10221022

1023+
// true when Type is objc's weak and weak is enabled but ARC isn't.
1024+
bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const;
1025+
10231026
enum DestructionKind {
10241027
DK_none,
10251028
DK_cxx_destructor,

Diff for: lib/AST/Type.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -2148,7 +2148,11 @@ bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
21482148
return false;
21492149
}
21502150

2151-
2151+
bool QualType::isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const {
2152+
return !Context.getLangOpts().ObjCAutoRefCount &&
2153+
Context.getLangOpts().ObjCWeak &&
2154+
getObjCLifetime() != Qualifiers::OCL_Weak;
2155+
}
21522156

21532157
bool Type::isLiteralType(const ASTContext &Ctx) const {
21542158
if (isDependentType())

Diff for: lib/Sema/SemaDecl.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -10167,7 +10167,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
1016710167
// we do not warn to warn spuriously when 'x' and 'y' are on separate
1016810168
// paths through the function. This should be revisited if
1016910169
// -Wrepeated-use-of-weak is made flow-sensitive.
10170-
if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong &&
10170+
if ((VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong ||
10171+
VDecl->getType().isNonWeakInMRRWithObjCWeak(Context)) &&
1017110172
!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
1017210173
Init->getLocStart()))
1017310174
getCurFunction()->markSafeWeakUse(Init);

Diff for: lib/Sema/SemaExpr.cpp

+11-7
Original file line numberDiff line numberDiff line change
@@ -704,8 +704,7 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
704704

705705
// Loading a __weak object implicitly retains the value, so we need a cleanup to
706706
// balance that.
707-
if (getLangOpts().ObjCAutoRefCount &&
708-
E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
707+
if (E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
709708
Cleanup.setExprNeedsCleanups(true);
710709

711710
ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E,
@@ -2509,11 +2508,11 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
25092508
ObjCIvarRefExpr(IV, IV->getUsageType(SelfExpr.get()->getType()), Loc,
25102509
IV->getLocation(), SelfExpr.get(), true, true);
25112510

2511+
if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
2512+
if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
2513+
recordUseOfEvaluatedWeak(Result);
2514+
}
25122515
if (getLangOpts().ObjCAutoRefCount) {
2513-
if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
2514-
if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
2515-
recordUseOfEvaluatedWeak(Result);
2516-
}
25172516
if (CurContext->isClosure())
25182517
Diag(Loc, diag::warn_implicitly_retains_self)
25192518
<< FixItHint::CreateInsertion(Loc, "self->");
@@ -10317,19 +10316,24 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
1031710316
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(InnerLHS);
1031810317
if (!DRE || DRE->getDecl()->hasAttr<BlocksAttr>())
1031910318
checkRetainCycles(LHSExpr, RHS.get());
10319+
}
1032010320

10321+
if (LHSType.getObjCLifetime() == Qualifiers::OCL_Strong ||
10322+
LHSType.isNonWeakInMRRWithObjCWeak(Context)) {
1032110323
// It is safe to assign a weak reference into a strong variable.
1032210324
// Although this code can still have problems:
1032310325
// id x = self.weakProp;
1032410326
// id y = self.weakProp;
1032510327
// we do not warn to warn spuriously when 'x' and 'y' are on separate
1032610328
// paths through the function. This should be revisited if
1032710329
// -Wrepeated-use-of-weak is made flow-sensitive.
10330+
// For ObjCWeak only, we do not warn if the assign is to a non-weak
10331+
// variable, which will be valid for the current autorelease scope.
1032810332
if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
1032910333
RHS.get()->getLocStart()))
1033010334
getCurFunction()->markSafeWeakUse(RHS.get());
1033110335

10332-
} else if (getLangOpts().ObjCAutoRefCount) {
10336+
} else if (getLangOpts().ObjCAutoRefCount || getLangOpts().ObjCWeak) {
1033310337
checkUnsafeExprAssigns(Loc, LHSExpr, RHS.get());
1033410338
}
1033510339
}

Diff for: lib/Sema/SemaExprMember.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -1496,7 +1496,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
14961496
}
14971497
}
14981498
bool warn = true;
1499-
if (S.getLangOpts().ObjCAutoRefCount) {
1499+
if (S.getLangOpts().ObjCWeak) {
15001500
Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
15011501
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
15021502
if (UO->getOpcode() == UO_Deref)
@@ -1523,11 +1523,9 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
15231523
IV, IV->getUsageType(BaseType), MemberLoc, OpLoc, BaseExpr.get(),
15241524
IsArrow);
15251525

1526-
if (S.getLangOpts().ObjCAutoRefCount) {
1527-
if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
1528-
if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
1529-
S.recordUseOfEvaluatedWeak(Result);
1530-
}
1526+
if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
1527+
if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
1528+
S.recordUseOfEvaluatedWeak(Result);
15311529
}
15321530

15331531
return Result;

Diff for: lib/Sema/SemaExprObjC.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -3100,7 +3100,9 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
31003100
// In ARC, check for message sends which are likely to introduce
31013101
// retain cycles.
31023102
checkRetainCycles(Result);
3103+
}
31033104

3105+
if (getLangOpts().ObjCWeak) {
31043106
if (!isImplicit && Method) {
31053107
if (const ObjCPropertyDecl *Prop = Method->findPropertyDecl()) {
31063108
bool IsWeak =

Diff for: lib/Sema/SemaPseudoObject.cpp

+7-9
Original file line numberDiff line numberDiff line change
@@ -842,12 +842,10 @@ ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
842842
result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
843843
}
844844
}
845-
if (S.getLangOpts().ObjCAutoRefCount) {
846-
Qualifiers::ObjCLifetime LT = propType.getObjCLifetime();
847-
if (LT == Qualifiers::OCL_Weak)
848-
if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation()))
849-
S.getCurFunction()->markSafeWeakUse(RefExpr);
850-
}
845+
if (propType.getObjCLifetime() == Qualifiers::OCL_Weak &&
846+
!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
847+
RefExpr->getLocation()))
848+
S.getCurFunction()->markSafeWeakUse(RefExpr);
851849
}
852850

853851
return result;
@@ -963,11 +961,11 @@ ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
963961
}
964962

965963
ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) {
966-
if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty() &&
964+
if (isWeakProperty() &&
967965
!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
968966
SyntacticForm->getLocStart()))
969-
S.recordUseOfEvaluatedWeak(SyntacticRefExpr,
970-
SyntacticRefExpr->isMessagingGetter());
967+
S.recordUseOfEvaluatedWeak(SyntacticRefExpr,
968+
SyntacticRefExpr->isMessagingGetter());
971969

972970
return PseudoOpBuilder::complete(SyntacticForm);
973971
}

Diff for: test/SemaObjC/arc-repeated-weak.mm

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// 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
2+
// 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
23

34
@interface Test {
45
@public
@@ -445,8 +446,8 @@ - (void) Meth : (id) data
445446
@class NSString;
446447
@interface NSBundle
447448
+(NSBundle *)foo;
448-
@property (class) NSBundle *foo2;
449-
@property NSString *prop;
449+
@property (class, strong) NSBundle *foo2;
450+
@property (strong) NSString *prop;
450451
@property(weak) NSString *weakProp;
451452
@end
452453

@@ -473,5 +474,8 @@ void foo() {
473474
};
474475

475476
void foo1() {
476-
INTFPtrTy tmp = (INTFPtrTy)e1; // expected-error{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}}
477+
INTFPtrTy tmp = (INTFPtrTy)e1;
478+
#if __has_feature(objc_arc)
479+
// expected-error@-2{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}}
480+
#endif
477481
}

0 commit comments

Comments
 (0)