Skip to content

Commit ab2cec8

Browse files
committed
[analyzer] Fix a crash on tracking Objective-C 'self' as a control dependency.
'self' was previously never tracked, but now it can be tracked because it may be part of a condition. llvm-svn: 375328
1 parent d7cf99a commit ab2cec8

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,14 +1418,19 @@ FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
14181418
if (Optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) {
14191419
if (const auto *VR = dyn_cast<VarRegion>(R)) {
14201420

1421-
const auto *Param = cast<ParmVarDecl>(VR->getDecl());
1421+
if (const auto *Param = dyn_cast<ParmVarDecl>(VR->getDecl())) {
1422+
ProgramStateManager &StateMgr = BRC.getStateManager();
1423+
CallEventManager &CallMgr = StateMgr.getCallEventManager();
14221424

1423-
ProgramStateManager &StateMgr = BRC.getStateManager();
1424-
CallEventManager &CallMgr = StateMgr.getCallEventManager();
1425-
1426-
CallEventRef<> Call = CallMgr.getCaller(CE->getCalleeContext(),
1427-
Succ->getState());
1428-
InitE = Call->getArgExpr(Param->getFunctionScopeIndex());
1425+
CallEventRef<> Call = CallMgr.getCaller(CE->getCalleeContext(),
1426+
Succ->getState());
1427+
InitE = Call->getArgExpr(Param->getFunctionScopeIndex());
1428+
} else {
1429+
// Handle Objective-C 'self'.
1430+
assert(isa<ImplicitParamDecl>(VR->getDecl()));
1431+
InitE = cast<ObjCMessageExpr>(CE->getCalleeContext()->getCallSite())
1432+
->getInstanceReceiver()->IgnoreParenCasts();
1433+
}
14291434
IsParam = true;
14301435
}
14311436
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,nullability -verify %s
2+
3+
// expected-no-diagnostics
4+
5+
@class C;
6+
7+
#pragma clang assume_nonnull begin
8+
@interface I
9+
- foo:(C *)c;
10+
@end
11+
#pragma clang assume_nonnull end
12+
13+
@interface J
14+
@property C *c;
15+
@end
16+
17+
J *conjure_J();
18+
19+
@implementation I
20+
- (void)bar {
21+
if (self) { // no-crash
22+
J *j = conjure_J();
23+
if (j.c)
24+
[self bar];
25+
// FIXME: Should warn.
26+
[self foo:j.c]; // no-warning
27+
}
28+
}
29+
@end
30+
31+
@implementation J
32+
@end

0 commit comments

Comments
 (0)