From b79b117d3b76da58b14ef835ccfcf2e988b7345f Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Fri, 22 Jan 2010 04:30:00 +0000 Subject: [PATCH] Process cast according to the cast kind. Prepare for more specific cast handling (for C++). No functionality change for now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94153 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Analysis/PathSensitive/GRExprEngine.h | 4 +- lib/Analysis/GRExprEngine.cpp | 64 ++++++++++++++----- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index fb0e88301f..df90ad9f7f 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -270,8 +270,8 @@ protected: ExplodedNodeSet& Dst, bool asLValue); /// VisitCast - Transfer function logic for all casts (implicit and explicit). - void VisitCast(Expr* CastE, Expr* Ex, ExplodedNode* Pred, - ExplodedNodeSet& Dst, bool asLValue); + void VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred, + ExplodedNodeSet &Dst, bool asLValue); /// VisitCompoundLiteralExpr - Transfer function logic for compound literals. void VisitCompoundLiteralExpr(CompoundLiteralExpr* CL, ExplodedNode* Pred, diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index b2229a268c..8f8d859e0c 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -2173,8 +2173,8 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME, // Transfer functions: Miscellaneous statements. //===----------------------------------------------------------------------===// -void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, ExplodedNode* Pred, - ExplodedNodeSet& Dst, bool asLValue){ +void GRExprEngine::VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred, + ExplodedNodeSet &Dst, bool asLValue) { ExplodedNodeSet S1; QualType T = CastE->getType(); QualType ExTy = Ex->getType(); @@ -2191,14 +2191,6 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, ExplodedNode* Pred, ExplodedNodeSet S2; CheckerVisit(CastE, S2, S1, true); - // Check for casting to "void". - if (T->isVoidType()) { - assert(!asLValue); - for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) - Dst.Add(*I); - return; - } - // If we are evaluating the cast in an lvalue context, we implicitly want // the cast to evaluate to a location. if (asLValue) { @@ -2207,13 +2199,51 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, ExplodedNode* Pred, ExTy = Ctx.getPointerType(Ctx.getCanonicalType(ExTy)); } - for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) { - ExplodedNode* N = *I; - const GRState* state = GetState(N); - SVal V = state->getSVal(Ex); - const SValuator::CastResult &Res = SVator.EvalCast(V, state, T, ExTy); - state = Res.getState()->BindExpr(CastE, Res.getSVal()); - MakeNode(Dst, CastE, N, state); + switch (CastE->getCastKind()) { + case CastExpr::CK_ToVoid: + assert(!asLValue); + for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) + Dst.Add(*I); + return; + + case CastExpr::CK_NoOp: + case CastExpr::CK_FunctionToPointerDecay: + for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) { + // Copy the SVal of Ex to CastE. + ExplodedNode *N = *I; + const GRState *state = GetState(N); + SVal V = state->getSVal(Ex); + state = state->BindExpr(CastE, V); + MakeNode(Dst, CastE, N, state); + } + return; + + case CastExpr::CK_Unknown: + case CastExpr::CK_ArrayToPointerDecay: + case CastExpr::CK_BitCast: + case CastExpr::CK_IntegralCast: + case CastExpr::CK_IntegralToPointer: + case CastExpr::CK_PointerToIntegral: + case CastExpr::CK_IntegralToFloating: + case CastExpr::CK_FloatingToIntegral: + case CastExpr::CK_FloatingCast: + case CastExpr::CK_AnyPointerToObjCPointerCast: + case CastExpr::CK_AnyPointerToBlockPointerCast: + case CastExpr::CK_DerivedToBase: + // Delegate to SValuator to process. + for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) { + ExplodedNode* N = *I; + const GRState* state = GetState(N); + SVal V = state->getSVal(Ex); + const SValuator::CastResult &Res = SVator.EvalCast(V, state, T, ExTy); + state = Res.getState()->BindExpr(CastE, Res.getSVal()); + MakeNode(Dst, CastE, N, state); + } + return; + + default: + llvm::errs() << "Cast kind " << CastE->getCastKind() << " not handled.\n"; + assert(0); } } -- 2.40.0