diff options
| author | Jordan Rose <jordan_rose@apple.com> | 2013-02-13 03:11:06 +0000 |
|---|---|---|
| committer | Jordan Rose <jordan_rose@apple.com> | 2013-02-13 03:11:06 +0000 |
| commit | 42b130b20a46d49b3d8bfb56d4bbc9624f0cd8e0 (patch) | |
| tree | 23a22d88f4f51ec78ac0d7375e60f50dd1bbd3fa /clang/lib | |
| parent | ff0dd946b176e652a762f6fb89f7b96e84bc4426 (diff) | |
| download | bcm5719-llvm-42b130b20a46d49b3d8bfb56d4bbc9624f0cd8e0.tar.gz bcm5719-llvm-42b130b20a46d49b3d8bfb56d4bbc9624f0cd8e0.zip | |
[analyzer] Use Clang's evaluation for global constants and default arguments.
Previously, we were handling only simple integer constants for globals and
the smattering of implicitly-valued expressions handled by Environment for
default arguments. Now, we can use any integer constant expression that
Clang can evaluate, in addition to everything we handled before.
PR15094 / <rdar://problem/12830437>
llvm-svn: 175026
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/Environment.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 34 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 13 |
3 files changed, 41 insertions, 10 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp index b6c44bf5d63..2b069a04a57 100644 --- a/clang/lib/StaticAnalyzer/Core/Environment.cpp +++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp @@ -37,9 +37,6 @@ static const Expr *ignoreTransparentExprs(const Expr *E) { case Stmt::SubstNonTypeTemplateParmExprClass: E = cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(); break; - case Stmt::CXXDefaultArgExprClass: - E = cast<CXXDefaultArgExpr>(E)->getExpr(); - break; default: // This is the base case: we can't look through more than we already have. return E; @@ -75,7 +72,6 @@ SVal Environment::getSVal(const EnvironmentEntry &Entry, switch (S->getStmtClass()) { case Stmt::CXXBindTemporaryExprClass: - case Stmt::CXXDefaultArgExprClass: case Stmt::ExprWithCleanupsClass: case Stmt::GenericSelectionExprClass: case Stmt::OpaqueValueExprClass: diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index f092f1a3d8d..18ac0964aa8 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -639,7 +639,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::StringLiteralClass: case Stmt::ObjCStringLiteralClass: case Stmt::CXXBindTemporaryExprClass: - case Stmt::CXXDefaultArgExprClass: case Stmt::SubstNonTypeTemplateParmExprClass: case Stmt::CXXNullPtrLiteralExprClass: { Bldr.takeNodes(Pred); @@ -650,6 +649,39 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, break; } + case Stmt::CXXDefaultArgExprClass: { + Bldr.takeNodes(Pred); + ExplodedNodeSet PreVisit; + getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); + + ExplodedNodeSet Tmp; + StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx); + + const LocationContext *LCtx = Pred->getLocationContext(); + const Expr *ArgE = cast<CXXDefaultArgExpr>(S)->getExpr(); + + // Avoid creating and destroying a lot of APSInts. + SVal V; + llvm::APSInt Result; + + for (ExplodedNodeSet::iterator I = PreVisit.begin(), E = PreVisit.end(); + I != E; ++I) { + ProgramStateRef State = (*I)->getState(); + + if (ArgE->EvaluateAsInt(Result, getContext())) + V = svalBuilder.makeIntVal(Result); + else + V = State->getSVal(ArgE, LCtx); + + State = State->BindExpr(S, LCtx, V); + Bldr2.generateNode(S, *I, State); + } + + getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); + Bldr.addNodes(Dst); + break; + } + case Expr::ObjCArrayLiteralClass: case Expr::ObjCDictionaryLiteralClass: // FIXME: explicitly model with a region and the actual contents diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 399f9ebae89..9572f648654 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1524,11 +1524,14 @@ SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B, QualType CT = Ctx.getCanonicalType(T); if (CT.isConstQualified()) { if (const Expr *Init = VD->getInit()) { - if (const IntegerLiteral *IL = - dyn_cast<IntegerLiteral>(Init->IgnoreParenCasts())) { - const nonloc::ConcreteInt &V = svalBuilder.makeIntVal(IL); - return svalBuilder.evalCast(V, Init->getType(), IL->getType()); - } + llvm::APSInt Result; + if (Init->EvaluateAsInt(Result, Ctx)) + return svalBuilder.makeIntVal(Result); + + if (Init->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull)) + return svalBuilder.makeNull(); + + // FIXME: Handle other possible constant expressions. } } |

