diff options
author | Jordan Rose <jordan_rose@apple.com> | 2013-02-25 19:45:34 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2013-02-25 19:45:34 +0000 |
commit | 77cdb53cdf91689ea27c4e75355d76fcb81c8fb4 (patch) | |
tree | bedf7d38c01f0542c3504e37eb560241f563198f | |
parent | a221e4e89cc3cba7b306716a7c7a5f287312c7f0 (diff) | |
download | bcm5719-llvm-77cdb53cdf91689ea27c4e75355d76fcb81c8fb4.tar.gz bcm5719-llvm-77cdb53cdf91689ea27c4e75355d76fcb81c8fb4.zip |
[analyzer] Handle reference parameters with default values.
r175026 added support for default values, but didn't take reference
parameters into account, which expect the default argument to be an
lvalue. Use createTemporaryRegionIfNeeded if we can evaluate the default
expr as an rvalue but the expected result is an lvalue.
Fixes the most recent report of PR12915. The original report predates
default argument support, so that can't be it.
llvm-svn: 176042
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 7 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 2 | ||||
-rw-r--r-- | clang/test/Analysis/global_region_invalidation.mm | 9 | ||||
-rw-r--r-- | clang/test/Analysis/inline.cpp | 9 |
4 files changed, 23 insertions, 4 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index eb83e202b77..8b6de132497 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -685,7 +685,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx); const LocationContext *LCtx = Pred->getLocationContext(); - const Expr *ArgE = cast<CXXDefaultArgExpr>(S)->getExpr(); + const CXXDefaultArgExpr *DefaultE = cast<CXXDefaultArgExpr>(S); + const Expr *ArgE = DefaultE->getExpr(); // Avoid creating and destroying a lot of APSInts. SVal V; @@ -700,7 +701,9 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, else V = State->getSVal(ArgE, LCtx); - State = State->BindExpr(S, LCtx, V); + State = State->BindExpr(DefaultE, LCtx, V); + if (DefaultE->isGLValue()) + State = createTemporaryRegionIfNeeded(State, LCtx, DefaultE); Bldr2.generateNode(S, *I, State); } diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 310c080fafb..acda9e0af32 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1578,7 +1578,7 @@ static Optional<SVal> getConstValue(SValBuilder &SVB, const VarDecl *VD) { return None; llvm::APSInt Result; - if (Init->EvaluateAsInt(Result, Ctx)) + if (!Init->isGLValue() && Init->EvaluateAsInt(Result, Ctx)) return SVB.makeIntVal(Result); if (Init->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull)) diff --git a/clang/test/Analysis/global_region_invalidation.mm b/clang/test/Analysis/global_region_invalidation.mm index 0d7f172b3f3..be337edab11 100644 --- a/clang/test/Analysis/global_region_invalidation.mm +++ b/clang/test/Analysis/global_region_invalidation.mm @@ -9,4 +9,11 @@ id foo(int x) { static id p = foo(1); clang_analyzer_eval(p == 0); // expected-warning{{TRUE}} return p; -}
\ No newline at end of file +} + +const int &globalInt = 42; + +void testGlobal() { + // FIXME: Should be TRUE, but should at least not crash. + clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}} +} diff --git a/clang/test/Analysis/inline.cpp b/clang/test/Analysis/inline.cpp index f0e69ddfc22..27853dc2aaf 100644 --- a/clang/test/Analysis/inline.cpp +++ b/clang/test/Analysis/inline.cpp @@ -260,6 +260,15 @@ namespace DefaultArgs { clang_analyzer_eval(complicatedExprUser(1) == 1); // expected-warning{{TRUE}} clang_analyzer_eval(complicatedExprUser() == 84); // expected-warning{{TRUE}} } + + int defaultReference(const int &input = 42) { + return input; + } + + void testReference() { + clang_analyzer_eval(defaultReference(1) == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(defaultReference() == 42); // expected-warning{{TRUE}} + } } namespace OperatorNew { |