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:
Zhongxing Xu 2010-11-24 08:53:20 +00:00
parent 9b6e6b087f
commit cb29802198
7 changed files with 36 additions and 39 deletions

View File

@ -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) {

View File

@ -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();

View File

@ -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 {

View File

@ -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());

View File

@ -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.

View File

@ -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);

View File

@ -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;