From 89bbd1fb6432f679b0c499c4a96f0907f494bb57 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Wed, 1 May 2013 23:10:44 +0000 Subject: [analyzer] Consolidate constant evaluation logic in SValBuilder. Previously, this was scattered across Environment (literal expressions), ExprEngine (default arguments), and RegionStore (global constants). The former special-cased several kinds of simple constant expressions, while the latter two deferred to the AST's constant evaluator. Now, these are all unified as SValBuilder::getConstantVal(). To keep Environment fast, the special cases for simple constant expressions have been left in, but the main benefits are that (a) unusual constants like ObjCStringLiterals now work as default arguments and global constant initializers, and (b) we're not duplicating code between ExprEngine and RegionStore. This actually caught a bug in our test suite, which is awesome: we stop tracking allocated memory if it's passed as an argument along with some kind of callback, but not if the callback is 0. We were testing this in a case where the callback parameter had a default value, but that value was 0. After this change, the analyzer now (correctly) flags that as a leak! llvm-svn: 180894 --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngine.cpp') diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 5b6e97d3fb4..0d5fb1785b3 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -741,20 +741,14 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, const CXXDefaultArgExpr *DefaultE = cast(S); const Expr *ArgE = DefaultE->getExpr(); - // Avoid creating and destroying a lot of APSInts. - SVal V; - llvm::APSInt Result; + Optional ConstantVal = svalBuilder.getConstantVal(ArgE); + if (!ConstantVal) + ConstantVal = UnknownVal(); 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(DefaultE, LCtx, V); + State = State->BindExpr(DefaultE, LCtx, *ConstantVal); if (DefaultE->isGLValue()) State = createTemporaryRegionIfNeeded(State, LCtx, DefaultE, DefaultE); -- cgit v1.2.3