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 | 38f68ef19cb51d5876e9025b5fceb44b33ec9ed7 (patch) | |
tree | 068ddb9e8bdda120632d421a06ddc96d7bdc13cc /lib/StaticAnalyzer/Core | |
parent | 04870edbea6cf88412c8c9c1eba65f7fc1fa12d9 (diff) |
[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>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175026 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core')
-rw-r--r-- | lib/StaticAnalyzer/Core/Environment.cpp | 4 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 34 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/RegionStore.cpp | 13 |
3 files changed, 41 insertions, 10 deletions
diff --git a/lib/StaticAnalyzer/Core/Environment.cpp b/lib/StaticAnalyzer/Core/Environment.cpp index b6c44bf5d6..2b069a04a5 100644 --- a/lib/StaticAnalyzer/Core/Environment.cpp +++ b/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/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index f092f1a3d8..18ac0964aa 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/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/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index 399f9ebae8..9572f64865 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/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. } } |