forked from OSchip/llvm-project
Use StackFrameContext directly in CallEnter program point. Then we don't need
to remake the stackframe everytime in GRExprEngine::ProcessCallEnter(). llvm-svn: 120087
This commit is contained in:
parent
9b6e6b087f
commit
cb29802198
|
@ -318,17 +318,16 @@ public:
|
||||||
|
|
||||||
class CallEnter : public StmtPoint {
|
class CallEnter : public StmtPoint {
|
||||||
public:
|
public:
|
||||||
// L is caller's location context. AC is callee's AnalysisContext.
|
CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx,
|
||||||
CallEnter(const Stmt *S, const AnalysisContext *AC, const LocationContext *L)
|
const LocationContext *callerCtx)
|
||||||
: StmtPoint(S, AC, CallEnterKind, L, 0) {}
|
: StmtPoint(stmt, calleeCtx, CallEnterKind, callerCtx, 0) {}
|
||||||
|
|
||||||
const Stmt *getCallExpr() const {
|
const Stmt *getCallExpr() const {
|
||||||
return static_cast<const Stmt *>(getData1());
|
return static_cast<const Stmt *>(getData1());
|
||||||
}
|
}
|
||||||
|
|
||||||
AnalysisContext *getCalleeContext() const {
|
const StackFrameContext *getCalleeContext() const {
|
||||||
return const_cast<AnalysisContext *>(
|
return static_cast<const StackFrameContext *>(getData2());
|
||||||
static_cast<const AnalysisContext *>(getData2()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool classof(const ProgramPoint *Location) {
|
static bool classof(const ProgramPoint *Location) {
|
||||||
|
|
|
@ -154,7 +154,7 @@ public:
|
||||||
|
|
||||||
bool hasIndexer() const { return Idxer != 0; }
|
bool hasIndexer() const { return Idxer != 0; }
|
||||||
|
|
||||||
const AnalysisContext *getAnalysisContextInAnotherTU(const Decl *D);
|
AnalysisContext *getAnalysisContextInAnotherTU(const Decl *D);
|
||||||
|
|
||||||
CFG *getCFG(Decl const *D) {
|
CFG *getCFG(Decl const *D) {
|
||||||
return AnaCtxMgr.getContext(D)->getCFG();
|
return AnaCtxMgr.getContext(D)->getCFG();
|
||||||
|
|
|
@ -482,11 +482,12 @@ class GRCallEnterNodeBuilder {
|
||||||
|
|
||||||
const ExplodedNode *Pred;
|
const ExplodedNode *Pred;
|
||||||
|
|
||||||
// The call site.
|
// The call site. For implicit automatic object dtor, this is the trigger
|
||||||
|
// statement.
|
||||||
const Stmt *CE;
|
const Stmt *CE;
|
||||||
|
|
||||||
// The AnalysisContext of the callee.
|
// The context of the callee.
|
||||||
AnalysisContext *CalleeCtx;
|
const StackFrameContext *CalleeCtx;
|
||||||
|
|
||||||
// The parent block of the CallExpr.
|
// The parent block of the CallExpr.
|
||||||
const CFGBlock *Block;
|
const CFGBlock *Block;
|
||||||
|
@ -496,7 +497,7 @@ class GRCallEnterNodeBuilder {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GRCallEnterNodeBuilder(GRCoreEngine &eng, const ExplodedNode *pred,
|
GRCallEnterNodeBuilder(GRCoreEngine &eng, const ExplodedNode *pred,
|
||||||
const Stmt *s, AnalysisContext *callee,
|
const Stmt *s, const StackFrameContext *callee,
|
||||||
const CFGBlock *blk, unsigned idx)
|
const CFGBlock *blk, unsigned idx)
|
||||||
: Eng(eng), Pred(pred), CE(s), CalleeCtx(callee), Block(blk), Index(idx) {}
|
: Eng(eng), Pred(pred), CE(s), CalleeCtx(callee), Block(blk), Index(idx) {}
|
||||||
|
|
||||||
|
@ -508,13 +509,13 @@ public:
|
||||||
|
|
||||||
const Stmt *getCallExpr() const { return CE; }
|
const Stmt *getCallExpr() const { return CE; }
|
||||||
|
|
||||||
AnalysisContext *getCalleeContext() const { return CalleeCtx; }
|
const StackFrameContext *getCalleeContext() const { return CalleeCtx; }
|
||||||
|
|
||||||
const CFGBlock *getBlock() const { return Block; }
|
const CFGBlock *getBlock() const { return Block; }
|
||||||
|
|
||||||
unsigned getIndex() const { return Index; }
|
unsigned getIndex() const { return Index; }
|
||||||
|
|
||||||
void GenerateNode(const GRState *state, const LocationContext *LocCtx);
|
void GenerateNode(const GRState *state);
|
||||||
};
|
};
|
||||||
|
|
||||||
class GRCallExitNodeBuilder {
|
class GRCallExitNodeBuilder {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
|
||||||
const AnalysisContext *
|
AnalysisContext *
|
||||||
AnalysisManager::getAnalysisContextInAnotherTU(const Decl *D) {
|
AnalysisManager::getAnalysisContextInAnotherTU(const Decl *D) {
|
||||||
idx::Entity Ent = idx::Entity::get(const_cast<Decl *>(D),
|
idx::Entity Ent = idx::Entity::get(const_cast<Decl *>(D),
|
||||||
Idxer->getProgram());
|
Idxer->getProgram());
|
||||||
|
|
|
@ -130,7 +130,7 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
|
||||||
const CXXThisRegion *ThisR =getCXXThisRegion(E->getConstructor()->getParent(),
|
const CXXThisRegion *ThisR =getCXXThisRegion(E->getConstructor()->getParent(),
|
||||||
SFC);
|
SFC);
|
||||||
|
|
||||||
CallEnter Loc(E, SFC->getAnalysisContext(), Pred->getLocationContext());
|
CallEnter Loc(E, SFC, Pred->getLocationContext());
|
||||||
for (ExplodedNodeSet::iterator NI = ArgsEvaluated.begin(),
|
for (ExplodedNodeSet::iterator NI = ArgsEvaluated.begin(),
|
||||||
NE = ArgsEvaluated.end(); NI != NE; ++NI) {
|
NE = ArgsEvaluated.end(); NI != NE; ++NI) {
|
||||||
const GRState *state = GetState(*NI);
|
const GRState *state = GetState(*NI);
|
||||||
|
@ -158,7 +158,7 @@ void GRExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD,
|
||||||
|
|
||||||
const CXXThisRegion *ThisR = getCXXThisRegion(DD->getParent(), SFC);
|
const CXXThisRegion *ThisR = getCXXThisRegion(DD->getParent(), SFC);
|
||||||
|
|
||||||
CallEnter PP(S, SFC->getAnalysisContext(), Pred->getLocationContext());
|
CallEnter PP(S, SFC, Pred->getLocationContext());
|
||||||
|
|
||||||
const GRState *state = Pred->getState();
|
const GRState *state = Pred->getState();
|
||||||
state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
|
state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
|
||||||
|
@ -243,7 +243,7 @@ void GRExprEngine::EvalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD,
|
||||||
Builder->getBlock(),
|
Builder->getBlock(),
|
||||||
Builder->getIndex());
|
Builder->getIndex());
|
||||||
const CXXThisRegion *ThisR = getCXXThisRegion(MD->getParent(), SFC);
|
const CXXThisRegion *ThisR = getCXXThisRegion(MD->getParent(), SFC);
|
||||||
CallEnter Loc(MCE, SFC->getAnalysisContext(), Pred->getLocationContext());
|
CallEnter Loc(MCE, SFC, Pred->getLocationContext());
|
||||||
for (ExplodedNodeSet::iterator I = PreVisitChecks.begin(),
|
for (ExplodedNodeSet::iterator I = PreVisitChecks.begin(),
|
||||||
E = PreVisitChecks.end(); I != E; ++I) {
|
E = PreVisitChecks.end(); I != E; ++I) {
|
||||||
// Set up 'this' region.
|
// Set up 'this' region.
|
||||||
|
|
|
@ -715,8 +715,7 @@ void GREndPathNodeBuilder::GenerateCallExitNode(const GRState *state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GRCallEnterNodeBuilder::GenerateNode(const GRState *state,
|
void GRCallEnterNodeBuilder::GenerateNode(const GRState *state) {
|
||||||
const LocationContext *LocCtx) {
|
|
||||||
// Check if the callee is in the same translation unit.
|
// Check if the callee is in the same translation unit.
|
||||||
if (CalleeCtx->getTranslationUnit() !=
|
if (CalleeCtx->getTranslationUnit() !=
|
||||||
Pred->getLocationContext()->getTranslationUnit()) {
|
Pred->getLocationContext()->getTranslationUnit()) {
|
||||||
|
@ -756,7 +755,7 @@ void GRCallEnterNodeBuilder::GenerateNode(const GRState *state,
|
||||||
// Create the new LocationContext.
|
// Create the new LocationContext.
|
||||||
AnalysisContext *NewAnaCtx = AMgr.getAnalysisContext(CalleeCtx->getDecl(),
|
AnalysisContext *NewAnaCtx = AMgr.getAnalysisContext(CalleeCtx->getDecl(),
|
||||||
CalleeCtx->getTranslationUnit());
|
CalleeCtx->getTranslationUnit());
|
||||||
const StackFrameContext *OldLocCtx = cast<StackFrameContext>(LocCtx);
|
const StackFrameContext *OldLocCtx = CalleeCtx;
|
||||||
const StackFrameContext *NewLocCtx = AMgr.getStackFrame(NewAnaCtx,
|
const StackFrameContext *NewLocCtx = AMgr.getStackFrame(NewAnaCtx,
|
||||||
OldLocCtx->getParent(),
|
OldLocCtx->getParent(),
|
||||||
OldLocCtx->getCallSite(),
|
OldLocCtx->getCallSite(),
|
||||||
|
@ -773,7 +772,7 @@ void GRCallEnterNodeBuilder::GenerateNode(const GRState *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the callee entry block.
|
// Get the callee entry block.
|
||||||
const CFGBlock *Entry = &(LocCtx->getCFG()->getEntry());
|
const CFGBlock *Entry = &(CalleeCtx->getCFG()->getEntry());
|
||||||
assert(Entry->empty());
|
assert(Entry->empty());
|
||||||
assert(Entry->succ_size() == 1);
|
assert(Entry->succ_size() == 1);
|
||||||
|
|
||||||
|
@ -781,7 +780,7 @@ void GRCallEnterNodeBuilder::GenerateNode(const GRState *state,
|
||||||
const CFGBlock *SuccB = *(Entry->succ_begin());
|
const CFGBlock *SuccB = *(Entry->succ_begin());
|
||||||
|
|
||||||
// Construct an edge representing the starting location in the callee.
|
// Construct an edge representing the starting location in the callee.
|
||||||
BlockEdge Loc(Entry, SuccB, LocCtx);
|
BlockEdge Loc(Entry, SuccB, CalleeCtx);
|
||||||
|
|
||||||
bool isNew;
|
bool isNew;
|
||||||
ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
|
ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
|
||||||
|
|
|
@ -1619,24 +1619,16 @@ void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRExprEngine::ProcessCallEnter(GRCallEnterNodeBuilder &B) {
|
void GRExprEngine::ProcessCallEnter(GRCallEnterNodeBuilder &B) {
|
||||||
const StackFrameContext *LocCtx
|
const GRState *state = B.getState()->EnterStackFrame(B.getCalleeContext());
|
||||||
= AMgr.getStackFrame(B.getCalleeContext(),
|
B.GenerateNode(state);
|
||||||
B.getLocationContext(),
|
|
||||||
B.getCallExpr(),
|
|
||||||
B.getBlock(),
|
|
||||||
B.getIndex());
|
|
||||||
|
|
||||||
const GRState *state = B.getState()->EnterStackFrame(LocCtx);
|
|
||||||
|
|
||||||
B.GenerateNode(state, LocCtx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRExprEngine::ProcessCallExit(GRCallExitNodeBuilder &B) {
|
void GRExprEngine::ProcessCallExit(GRCallExitNodeBuilder &B) {
|
||||||
const GRState *state = B.getState();
|
const GRState *state = B.getState();
|
||||||
const ExplodedNode *Pred = B.getPredecessor();
|
const ExplodedNode *Pred = B.getPredecessor();
|
||||||
const StackFrameContext *LocCtx =
|
const StackFrameContext *calleeCtx =
|
||||||
cast<StackFrameContext>(Pred->getLocationContext());
|
cast<StackFrameContext>(Pred->getLocationContext());
|
||||||
const Stmt *CE = LocCtx->getCallSite();
|
const Stmt *CE = calleeCtx->getCallSite();
|
||||||
|
|
||||||
// If the callee returns an expression, bind its value to CallExpr.
|
// If the callee returns an expression, bind its value to CallExpr.
|
||||||
const Stmt *ReturnedExpr = state->get<ReturnExpr>();
|
const Stmt *ReturnedExpr = state->get<ReturnExpr>();
|
||||||
|
@ -1650,7 +1642,7 @@ void GRExprEngine::ProcessCallExit(GRCallExitNodeBuilder &B) {
|
||||||
// Bind the constructed object value to CXXConstructExpr.
|
// Bind the constructed object value to CXXConstructExpr.
|
||||||
if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
|
if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
|
||||||
const CXXThisRegion *ThisR =
|
const CXXThisRegion *ThisR =
|
||||||
getCXXThisRegion(CCE->getConstructor()->getParent(), LocCtx);
|
getCXXThisRegion(CCE->getConstructor()->getParent(), calleeCtx);
|
||||||
// We might not have 'this' region in the binding if we didn't inline
|
// We might not have 'this' region in the binding if we didn't inline
|
||||||
// the ctor call.
|
// the ctor call.
|
||||||
SVal ThisV = state->getSVal(ThisR);
|
SVal ThisV = state->getSVal(ThisR);
|
||||||
|
@ -2078,8 +2070,12 @@ bool GRExprEngine::InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE,
|
||||||
|
|
||||||
// Check if the function definition is in the same translation unit.
|
// Check if the function definition is in the same translation unit.
|
||||||
if (FD->hasBody(FD)) {
|
if (FD->hasBody(FD)) {
|
||||||
|
const StackFrameContext *stackFrame =
|
||||||
|
AMgr.getStackFrame(AMgr.getAnalysisContext(FD),
|
||||||
|
Pred->getLocationContext(),
|
||||||
|
CE, Builder->getBlock(), Builder->getIndex());
|
||||||
// Now we have the definition of the callee, create a CallEnter node.
|
// Now we have the definition of the callee, create a CallEnter node.
|
||||||
CallEnter Loc(CE, AMgr.getAnalysisContext(FD), Pred->getLocationContext());
|
CallEnter Loc(CE, stackFrame, Pred->getLocationContext());
|
||||||
|
|
||||||
ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
|
ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
|
||||||
Dst.Add(N);
|
Dst.Add(N);
|
||||||
|
@ -2088,11 +2084,13 @@ bool GRExprEngine::InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE,
|
||||||
|
|
||||||
// Check if we can find the function definition in other translation units.
|
// Check if we can find the function definition in other translation units.
|
||||||
if (AMgr.hasIndexer()) {
|
if (AMgr.hasIndexer()) {
|
||||||
const AnalysisContext *C = AMgr.getAnalysisContextInAnotherTU(FD);
|
AnalysisContext *C = AMgr.getAnalysisContextInAnotherTU(FD);
|
||||||
if (C == 0)
|
if (C == 0)
|
||||||
return false;
|
return false;
|
||||||
|
const StackFrameContext *stackFrame =
|
||||||
CallEnter Loc(CE, C, Pred->getLocationContext());
|
AMgr.getStackFrame(C, Pred->getLocationContext(),
|
||||||
|
CE, Builder->getBlock(), Builder->getIndex());
|
||||||
|
CallEnter Loc(CE, stackFrame, Pred->getLocationContext());
|
||||||
ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
|
ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
|
||||||
Dst.Add(N);
|
Dst.Add(N);
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue