summaryrefslogtreecommitdiffstats
path: root/clang/lib/Checker
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2010-02-26 15:43:34 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2010-02-26 15:43:34 +0000
commit5c07584f44a93d44a8224219e0e1131cd07dafb0 (patch)
tree42b192acf911d736036ea97bad6ac9a2af0761f8 /clang/lib/Checker
parente750212f8c1b0613fb019b627d96bca391eb72dc (diff)
downloadbcm5719-llvm-5c07584f44a93d44a8224219e0e1131cd07dafb0.tar.gz
bcm5719-llvm-5c07584f44a93d44a8224219e0e1131cd07dafb0.zip
Use a GDM to record the returned expression in the state when VisitReturnStmt.
Use this information to find the returned value and bind it to CallExpr in ProcessCallExit. And there is no need to remove dead bindings in ProcessCallExit, because a. it would clean up the return value bound to CallExpr b. we still would do it in the next ProcessStmt(), where we would not misclean up the return value. llvm-svn: 97225
Diffstat (limited to 'clang/lib/Checker')
-rw-r--r--clang/lib/Checker/GRExprEngine.cpp38
1 files changed, 28 insertions, 10 deletions
diff --git a/clang/lib/Checker/GRExprEngine.cpp b/clang/lib/Checker/GRExprEngine.cpp
index aadfa528df1..964f7fac896 100644
--- a/clang/lib/Checker/GRExprEngine.cpp
+++ b/clang/lib/Checker/GRExprEngine.cpp
@@ -37,6 +37,15 @@ using llvm::dyn_cast_or_null;
using llvm::cast;
using llvm::APSInt;
+namespace {
+ // Trait class for recording returned expression in the state.
+ struct ReturnExpr {
+ static int TagInt;
+ typedef const Stmt *data_type;
+ };
+ int ReturnExpr::TagInt;
+}
+
//===----------------------------------------------------------------------===//
// Utility functions.
//===----------------------------------------------------------------------===//
@@ -1309,16 +1318,15 @@ void GRExprEngine::ProcessCallExit(GRCallExitNodeBuilder &B) {
const ExplodedNode *Pred = B.getPredecessor();
const StackFrameContext *LocCtx =
cast<StackFrameContext>(Pred->getLocationContext());
- const StackFrameContext *ParentSF =
- cast<StackFrameContext>(LocCtx->getParent());
-
- SymbolReaper SymReaper(*ParentSF->getLiveVariables(), getSymbolManager(),
- ParentSF);
const Stmt *CE = LocCtx->getCallSite();
- state = getStateManager().RemoveDeadBindings(state, const_cast<Stmt*>(CE),
- SymReaper);
-
+ // If the callee returns an expression, bind its value to CallExpr.
+ const Stmt *ReturnedExpr = state->get<ReturnExpr>();
+ if (ReturnedExpr) {
+ SVal RetVal = state->getSVal(ReturnedExpr);
+ state = state->BindExpr(CE, RetVal);
+ }
+
B.GenerateNode(state);
}
@@ -2889,10 +2897,20 @@ void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A,
void GRExprEngine::VisitReturnStmt(ReturnStmt *RS, ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
-
ExplodedNodeSet Src;
if (Expr *RetE = RS->getRetValue()) {
- Visit(RetE, Pred, Src);
+ // Record the returned expression in the state.
+ {
+ static int Tag;
+ SaveAndRestore<const void *> OldTag(Builder->Tag);
+ Builder->Tag = &Tag;
+ const GRState *state = GetState(Pred);
+ state = state->set<ReturnExpr>(RetE);
+ Pred = Builder->generateNode(RetE, state, Pred);
+ }
+ // We may get a NULL Pred because we generated a cached node.
+ if (Pred)
+ Visit(RetE, Pred, Src);
}
else {
Src.Add(Pred);
OpenPOWER on IntegriCloud