aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp2
-rw-r--r--test/Analysis/global_region_invalidation.mm9
-rw-r--r--test/Analysis/inline.cpp9
4 files changed, 23 insertions, 4 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index eb83e202b7..8b6de13249 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/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/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index 310c080faf..acda9e0af3 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/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/test/Analysis/global_region_invalidation.mm b/test/Analysis/global_region_invalidation.mm
index 0d7f172b3f..be337edab1 100644
--- a/test/Analysis/global_region_invalidation.mm
+++ b/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/test/Analysis/inline.cpp b/test/Analysis/inline.cpp
index f0e69ddfc2..27853dc2aa 100644
--- a/test/Analysis/inline.cpp
+++ b/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 {