diff options
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 2 | ||||
-rw-r--r-- | clang/test/Analysis/temporaries.cpp | 36 |
2 files changed, 36 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 888963359b4..a5bd74f9204 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -596,8 +596,6 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE, for (InitListExpr::const_reverse_iterator it = IE->rbegin(), ei = IE->rend(); it != ei; ++it) { SVal V = state->getSVal(cast<Expr>(*it), LCtx); - if (dyn_cast_or_null<CXXTempObjectRegion>(V.getAsRegion())) - V = UnknownVal(); vals = getBasicVals().consVals(V, vals); } diff --git a/clang/test/Analysis/temporaries.cpp b/clang/test/Analysis/temporaries.cpp index ea4abb2d843..5e1771cc441 100644 --- a/clang/test/Analysis/temporaries.cpp +++ b/clang/test/Analysis/temporaries.cpp @@ -157,3 +157,39 @@ void testStaticMaterializeTemporaryExpr() { clang_analyzer_eval(threadDirectRef.value == 42); // expected-warning{{TRUE}} #endif } + +namespace PR16629 { + struct A { + explicit A(int* p_) : p(p_) {} + int* p; + }; + + extern void escape(const A*[]); + extern void check(int); + + void callEscape(const A& a) { + const A* args[] = { &a }; + escape(args); + } + + void testNoWarning() { + int x; + callEscape(A(&x)); + check(x); // Analyzer used to give a "x is uninitialized warning" here + } + + void set(const A*a[]) { + *a[0]->p = 47; + } + + void callSet(const A& a) { + const A* args[] = { &a }; + set(args); + } + + void testConsistency() { + int x; + callSet(A(&x)); + clang_analyzer_eval(x == 47); // expected-warning{{TRUE}} + } +} |