From 88f07cd49c45a91520c032334854e2b15c712b06 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Sat, 5 Sep 2009 05:00:57 +0000 Subject: [PATCH] Refactor builtin function evaluation code into its own function. llvm-svn: 81061 --- .../Analysis/PathSensitive/GRExprEngine.h | 3 + clang/lib/Analysis/GRExprEngine.cpp | 77 +++++++++++-------- 2 files changed, 47 insertions(+), 33 deletions(-) diff --git a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h index 4e6e74d60ac9..1410c011c798 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -578,6 +578,9 @@ protected: SVal EvalComplement(SVal X) { return X.isValid() ? SVator.EvalComplement(cast(X)) : X; } + + bool EvalBuiltinFunction(const FunctionDecl *FD, CallExpr *CE, + ExplodedNode *Pred, ExplodedNodeSet &Dst); public: diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp index df31c3f53be6..187d03e43ebf 100644 --- a/clang/lib/Analysis/GRExprEngine.cpp +++ b/clang/lib/Analysis/GRExprEngine.cpp @@ -1503,6 +1503,46 @@ static void MarkNoReturnFunction(const FunctionDecl *FD, CallExpr *CE, } } +bool GRExprEngine::EvalBuiltinFunction(const FunctionDecl *FD, CallExpr *CE, + ExplodedNode *Pred, + ExplodedNodeSet &Dst) { + if (!FD) + return false; + + unsigned id = FD->getBuiltinID(getContext()); + if (!id) + return false; + + const GRState *state = Pred->getState(); + + switch (id) { + case Builtin::BI__builtin_expect: { + // For __builtin_expect, just return the value of the subexpression. + assert (CE->arg_begin() != CE->arg_end()); + SVal X = state->getSVal(*(CE->arg_begin())); + MakeNode(Dst, CE, Pred, state->BindExpr(CE, X)); + return true; + } + + case Builtin::BI__builtin_alloca: { + // FIXME: Refactor into StoreManager itself? + MemRegionManager& RM = getStateManager().getRegionManager(); + const MemRegion* R = + RM.getAllocaRegion(CE, Builder->getCurrentBlockCount()); + + // Set the extent of the region in bytes. This enables us to use the + // SVal of the argument directly. If we save the extent in bits, we + // cannot represent values like symbol*8. + SVal Extent = state->getSVal(*(CE->arg_begin())); + state = getStoreManager().setExtent(state, R, Extent); + MakeNode(Dst, CE, Pred, state->BindExpr(CE, loc::MemRegionVal(R))); + return true; + } + } + + return false; +} + void GRExprEngine::EvalCall(ExplodedNodeSet& Dst, CallExpr* CE, SVal L, ExplodedNode* Pred) { assert (Builder && "GRStmtNodeBuilder must be defined."); @@ -1571,7 +1611,8 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, ExplodedNode* Pred, } // Finally, evaluate the function call. - for (ExplodedNodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end(); DI!=DE; ++DI) { + for (ExplodedNodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end(); + DI != DE; ++DI) { const GRState* state = GetState(*DI); SVal L = state->getSVal(Callee); @@ -1587,38 +1628,8 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, ExplodedNode* Pred, MarkNoReturnFunction(FD, CE, state, Builder); // Evaluate the call. - - if (FD) { - - if (unsigned id = FD->getBuiltinID(getContext())) - switch (id) { - case Builtin::BI__builtin_expect: { - // For __builtin_expect, just return the value of the subexpression. - assert (CE->arg_begin() != CE->arg_end()); - SVal X = state->getSVal(*(CE->arg_begin())); - MakeNode(Dst, CE, *DI, state->BindExpr(CE, X)); - continue; - } - - case Builtin::BI__builtin_alloca: { - // FIXME: Refactor into StoreManager itself? - MemRegionManager& RM = getStateManager().getRegionManager(); - const MemRegion* R = - RM.getAllocaRegion(CE, Builder->getCurrentBlockCount()); - - // Set the extent of the region in bytes. This enables us to use the - // SVal of the argument directly. If we save the extent in bits, we - // cannot represent values like symbol*8. - SVal Extent = state->getSVal(*(CE->arg_begin())); - state = getStoreManager().setExtent(state, R, Extent); - MakeNode(Dst, CE, *DI, state->BindExpr(CE, loc::MemRegionVal(R))); - continue; - } - - default: - break; - } - } + if (EvalBuiltinFunction(FD, CE, Pred, Dst)) + continue; // Dispatch to the plug-in transfer function.