[cfe-commits] r160021 - in /cfe/trunk: include/clang/Analysis/ProgramPoint.h lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp lib/StaticAnalyzer/Checkers/MallocChecker.cpp lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp lib/StaticAnalyzer/Core/BugReporter.cpp lib/StaticAnalyzer/Core/CoreEngine.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp lib/StaticAnalyzer/Core/PathDiagnostic.cpp
Jordan Rose
jordan_rose at apple.com
Tue Jul 10 15:07:52 PDT 2012
Author: jrose
Date: Tue Jul 10 17:07:52 2012
New Revision: 160021
URL: http://llvm.org/viewvc/llvm-project?rev=160021&view=rev
Log:
[analyzer] Make CallEnter, CallExitBegin, and CallExitEnd not be StmtPoints
These ProgramPoints are used in inlining calls,
and not all calls have associated statements anymore.
Modified:
cfe/trunk/include/clang/Analysis/ProgramPoint.h
cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
Modified: cfe/trunk/include/clang/Analysis/ProgramPoint.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/ProgramPoint.h?rev=160021&r1=160020&r2=160021&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/ProgramPoint.h (original)
+++ cfe/trunk/include/clang/Analysis/ProgramPoint.h Tue Jul 10 17:07:52 2012
@@ -49,12 +49,12 @@
PostStoreKind,
PostConditionKind,
PostLValueKind,
+ MinPostStmtKind = PostStmtKind,
+ MaxPostStmtKind = PostLValueKind,
PostInitializerKind,
CallEnterKind,
CallExitBeginKind,
CallExitEndKind,
- MinPostStmtKind = PostStmtKind,
- MaxPostStmtKind = CallExitEndKind,
PreImplicitCallKind,
PostImplicitCallKind,
MinImplicitCallKind = PreImplicitCallKind,
@@ -461,11 +461,11 @@
};
/// Represents a point when we begin processing an inlined call.
-class CallEnter : public StmtPoint {
+class CallEnter : public ProgramPoint {
public:
CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx,
const LocationContext *callerCtx)
- : StmtPoint(stmt, calleeCtx, CallEnterKind, callerCtx, 0) {}
+ : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, 0) {}
const Stmt *getCallExpr() const {
return static_cast<const Stmt *>(getData1());
@@ -489,11 +489,11 @@
/// - Bind the return value
/// - Run Remove dead bindings (to clean up the dead symbols from the callee).
/// - CallExitEnd
-class CallExitBegin : public StmtPoint {
+class CallExitBegin : public ProgramPoint {
public:
// CallExitBegin uses the callee's location context.
- CallExitBegin(const Stmt *S, const LocationContext *L)
- : StmtPoint(S, 0, CallExitBeginKind, L, 0) {}
+ CallExitBegin(const StackFrameContext *L)
+ : ProgramPoint(0, CallExitBeginKind, L, 0) {}
static bool classof(const ProgramPoint *Location) {
return Location->getKind() == CallExitBeginKind;
@@ -502,11 +502,16 @@
/// Represents a point when we finish the call exit sequence (for inlined call).
/// \sa CallExitBegin
-class CallExitEnd : public StmtPoint {
+class CallExitEnd : public ProgramPoint {
public:
// CallExitEnd uses the caller's location context.
- CallExitEnd(const Stmt *S, const LocationContext *L)
- : StmtPoint(S, 0, CallExitEndKind, L, 0) {}
+ CallExitEnd(const StackFrameContext *CalleeCtx,
+ const LocationContext *CallerCtx)
+ : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, 0) {}
+
+ const StackFrameContext *getCalleeContext() const {
+ return static_cast<const StackFrameContext *>(getData1());
+ }
static bool classof(const ProgramPoint *Location) {
return Location->getKind() == CallExitEndKind;
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp?rev=160021&r1=160020&r2=160021&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp Tue Jul 10 17:07:52 2012
@@ -528,9 +528,11 @@
}
ProgramPoint P = AllocNode->getLocation();
- if (!isa<StmtPoint>(P))
- return 0;
- return cast<clang::PostStmt>(P).getStmt();
+ if (CallExitEnd *Exit = dyn_cast<CallExitEnd>(&P))
+ return Exit->getCalleeContext()->getCallSite();
+ if (clang::PostStmt *PS = dyn_cast<clang::PostStmt>(&P))
+ return PS->getStmt();
+ return 0;
}
BugReport *MacOSKeychainAPIChecker::
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=160021&r1=160020&r2=160021&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Tue Jul 10 17:07:52 2012
@@ -972,8 +972,10 @@
ProgramPoint P = AllocNode->getLocation();
const Stmt *AllocationStmt = 0;
- if (isa<StmtPoint>(P))
- AllocationStmt = cast<StmtPoint>(P).getStmt();
+ if (CallExitEnd *Exit = dyn_cast<CallExitEnd>(&P))
+ AllocationStmt = Exit->getCalleeContext()->getCallSite();
+ else if (StmtPoint *SP = dyn_cast<StmtPoint>(&P))
+ AllocationStmt = SP->getStmt();
return LeakInfo(AllocationStmt, ReferenceRegion);
}
@@ -1524,12 +1526,14 @@
// Retrieve the associated statement.
ProgramPoint ProgLoc = N->getLocation();
- if (isa<StmtPoint>(ProgLoc))
- S = cast<StmtPoint>(ProgLoc).getStmt();
+ if (StmtPoint *SP = dyn_cast<StmtPoint>(&ProgLoc))
+ S = SP->getStmt();
+ else if (CallExitEnd *Exit = dyn_cast<CallExitEnd>(&ProgLoc))
+ S = Exit->getCalleeContext()->getCallSite();
// If an assumption was made on a branch, it should be caught
// here by looking at the state transition.
- if (isa<BlockEdge>(ProgLoc)) {
- const CFGBlock *srcBlk = cast<BlockEdge>(ProgLoc).getSrc();
+ else if (BlockEdge *Edge = dyn_cast<BlockEdge>(&ProgLoc)) {
+ const CFGBlock *srcBlk = Edge->getSrc();
S = srcBlk->getTerminator();
}
if (!S)
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=160021&r1=160020&r2=160021&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Tue Jul 10 17:07:52 2012
@@ -2352,8 +2352,15 @@
GetAllocationSite(Ctx.getStateManager(), getErrorNode(), sym);
// Get the SourceLocation for the allocation site.
+ // FIXME: This will crash the analyzer if an allocation comes from an
+ // implicit call. (Currently there are no such allocations in Cocoa, though.)
+ const Stmt *AllocStmt;
ProgramPoint P = AllocNode->getLocation();
- const Stmt *AllocStmt = cast<PostStmt>(P).getStmt();
+ if (CallExitEnd *Exit = dyn_cast<CallExitEnd>(&P))
+ AllocStmt = Exit->getCalleeContext()->getCallSite();
+ else
+ AllocStmt = cast<PostStmt>(P).getStmt();
+ assert(AllocStmt && "All allocations must come from explicit calls");
Location = PathDiagnosticLocation::createBegin(AllocStmt, SMgr,
n->getLocationContext());
// Fill in the description of the bug.
Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=160021&r1=160020&r2=160021&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp Tue Jul 10 17:07:52 2012
@@ -48,6 +48,10 @@
return SP->getStmt();
else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P))
return BE->getSrc()->getTerminator();
+ else if (const CallEnter *CE = dyn_cast<CallEnter>(&P))
+ return CE->getCallExpr();
+ else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&P))
+ return CEE->getCalleeContext()->getCallSite();
return 0;
}
@@ -1102,11 +1106,10 @@
const LocationContext *CalleeCtx,
const LocationContext *CallerCtx)
{
- // FIXME: Handle CXXConstructExpr.
- // FIXME: Handle calls to blocks.
+ // FIXME: Handle non-CallExpr-based CallEvents.
const StackFrameContext *Callee = CalleeCtx->getCurrentStackFrame();
const Stmt *CallSite = Callee->getCallSite();
- if (const CallExpr *CE = dyn_cast<CallExpr>(CallSite)) {
+ if (const CallExpr *CE = dyn_cast_or_null<CallExpr>(CallSite)) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeCtx->getDecl())) {
FunctionDecl::param_const_iterator PI = FD->param_begin(),
PE = FD->param_end();
@@ -1149,17 +1152,24 @@
if (const CallExitEnd *CE = dyn_cast<CallExitEnd>(&P)) {
const StackFrameContext *LCtx =
- CE->getLocationContext()->getCurrentStackFrame();
- PathDiagnosticLocation Loc(CE->getStmt(),
- PDB.getSourceManager(),
- LCtx);
- EB.addEdge(Loc, true);
- EB.flushLocations();
- PathDiagnosticCallPiece *C =
- PathDiagnosticCallPiece::construct(N, *CE, SM);
- PD.getActivePath().push_front(C);
- PD.pushActivePath(&C->path);
- CallStack.push_back(StackDiagPair(C, N));
+ CE->getLocationContext()->getCurrentStackFrame();
+ // FIXME: This needs to handle implicit calls.
+ if (const Stmt *S = CE->getCalleeContext()->getCallSite()) {
+ if (const Expr *Ex = dyn_cast<Expr>(S))
+ reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
+ N->getState().getPtr(), Ex,
+ N->getLocationContext());
+ PathDiagnosticLocation Loc(S,
+ PDB.getSourceManager(),
+ LCtx);
+ EB.addEdge(Loc, true);
+ EB.flushLocations();
+ PathDiagnosticCallPiece *C =
+ PathDiagnosticCallPiece::construct(N, *CE, SM);
+ PD.getActivePath().push_front(C);
+ PD.pushActivePath(&C->path);
+ CallStack.push_back(StackDiagPair(C, N));
+ }
break;
}
@@ -1191,8 +1201,12 @@
const Decl * Caller = CE->getLocationContext()->getDecl();
C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
}
- C->setCallee(*CE, SM);
- EB.addContext(CE->getCallExpr());
+
+ // FIXME: We still need a location for implicit calls.
+ if (CE->getCallExpr()) {
+ C->setCallee(*CE, SM);
+ EB.addContext(CE->getCallExpr());
+ }
if (!CallStack.empty()) {
assert(CallStack.back().first == C);
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=160021&r1=160020&r2=160021&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Tue Jul 10 17:07:52 2012
@@ -265,7 +265,8 @@
}
default:
assert(isa<PostStmt>(Loc) ||
- isa<PostInitializer>(Loc));
+ isa<PostInitializer>(Loc) ||
+ isa<CallExitEnd>(Loc));
HandlePostStmt(WU.getBlock(), WU.getIndex(), Pred);
break;
}
@@ -539,10 +540,9 @@
// Create a CallExitBegin node and enqueue it.
const StackFrameContext *LocCtx
= cast<StackFrameContext>(N->getLocationContext());
- const Stmt *CE = LocCtx->getCallSite();
// Use the the callee location context.
- CallExitBegin Loc(CE, LocCtx);
+ CallExitBegin Loc(LocCtx);
bool isNew;
ExplodedNode *Node = G->getNode(Loc, N->getState(), false, &isNew);
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=160021&r1=160020&r2=160021&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Jul 10 17:07:52 2012
@@ -1001,6 +1001,8 @@
continue;
if (isa<PreImplicitCall>(&L))
continue;
+ if (isa<CallEnter>(&L))
+ continue;
if (const StmtPoint *SP = dyn_cast<StmtPoint>(&L))
if (SP->getStmt() == CE)
continue;
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=160021&r1=160020&r2=160021&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Tue Jul 10 17:07:52 2012
@@ -134,23 +134,25 @@
const CFGBlock *Blk = 0;
llvm::tie(LastSt, Blk) = getLastStmt(CEBNode);
- // Step 2: generate node with binded return value: CEBNode -> BindedRetNode.
+ // Step 2: generate node with bound return value: CEBNode -> BindedRetNode.
// If the callee returns an expression, bind its value to CallExpr.
- if (const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
- const LocationContext *LCtx = CEBNode->getLocationContext();
- SVal V = state->getSVal(RS, LCtx);
- state = state->BindExpr(CE, callerCtx, V);
- }
+ if (CE) {
+ if (const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
+ const LocationContext *LCtx = CEBNode->getLocationContext();
+ SVal V = state->getSVal(RS, LCtx);
+ state = state->BindExpr(CE, callerCtx, V);
+ }
- // Bind the constructed object value to CXXConstructExpr.
- if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
- loc::MemRegionVal This =
- svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
- SVal ThisV = state->getSVal(This);
+ // Bind the constructed object value to CXXConstructExpr.
+ if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
+ loc::MemRegionVal This =
+ svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
+ SVal ThisV = state->getSVal(This);
- // Always bind the region to the CXXConstructExpr.
- state = state->BindExpr(CCE, CEBNode->getLocationContext(), ThisV);
+ // Always bind the region to the CXXConstructExpr.
+ state = state->BindExpr(CCE, CEBNode->getLocationContext(), ThisV);
+ }
}
static SimpleProgramPointTag retValBindTag("ExprEngine : Bind Return Value");
@@ -186,7 +188,7 @@
// Step 4: Generate the CallExit and leave the callee's context.
// CleanedNodes -> CEENode
- CallExitEnd Loc(CE, callerCtx);
+ CallExitEnd Loc(calleeCtx, callerCtx);
bool isNew;
ExplodedNode *CEENode = G.getNode(Loc, (*I)->getState(), false, &isNew);
CEENode->addPredecessor(*I, G);
@@ -202,7 +204,9 @@
&Ctx);
SaveAndRestore<unsigned> CBISave(currentStmtIdx, calleeCtx->getIndex());
- getCheckerManager().runCheckersForPostStmt(Dst, CEENode, CE, *this, true);
+ // FIXME: This needs to call PostCall.
+ if (CE)
+ getCheckerManager().runCheckersForPostStmt(Dst, CEENode, CE, *this, true);
// Enqueue the next element in the block.
for (ExplodedNodeSet::iterator PSI = Dst.begin(), PSE = Dst.end();
@@ -322,8 +326,8 @@
if (!ParentOfCallee)
ParentOfCallee = CallerSFC;
+ // This may be NULL, but that's fine.
const Expr *CallE = Call.getOriginExpr();
- assert(CallE && "It is not yet possible to have calls without statements");
// Construct a new stack frame for the callee.
AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
Modified: cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp?rev=160021&r1=160020&r2=160021&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Tue Jul 10 17:07:52 2012
@@ -339,6 +339,9 @@
else if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
S = PS->getStmt();
}
+ else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&P)) {
+ S = CEE->getCalleeContext()->getCallSite();
+ }
return PathDiagnosticLocation(S, SMng, P.getLocationContext());
}
@@ -501,6 +504,10 @@
ProgramPoint PP = N->getLocation();
if (const StmtPoint *SP = dyn_cast<StmtPoint>(&PP))
return PathDiagnosticLocation(SP->getStmt(), SM, PP.getLocationContext());
+ // FIXME: Handle implicit calls.
+ if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&PP))
+ if (const Stmt *CallSite = CEE->getCalleeContext()->getCallSite())
+ return PathDiagnosticLocation(CallSite, SM, PP.getLocationContext());
if (N->pred_empty())
break;
N = *N->pred_begin();
@@ -670,7 +677,8 @@
const CallExitEnd *CExit = dyn_cast<CallExitEnd>(&P);
assert(CExit && "Stack Hints should be constructed at CallExitEnd points.");
- const CallExpr *CE = dyn_cast_or_null<CallExpr>(CExit->getStmt());
+ const Stmt *CallSite = CExit->getCalleeContext()->getCallSite();
+ const CallExpr *CE = dyn_cast_or_null<CallExpr>(CallSite);
if (!CE)
return "";
More information about the cfe-commits
mailing list