From: Pavel Labath Date: Fri, 9 Aug 2013 07:46:29 +0000 (+0000) Subject: [analyzer] Enable usage of temporaries in InitListExprs X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6ebe9df900b79fd56a4db03b4f8aa6a180307a9d;p=clang [analyzer] Enable usage of temporaries in InitListExprs Summary: ExprEngine had code which specificaly disabled using CXXTempObjectRegions in InitListExprs. This was a hack put in r168757 to silence a false positive. The underlying problem seems to have been fixed in the mean time, as removing this code doesn't seem to break anything. Therefore I propose to remove it and solve PR16629 in the process. Reviewers: jordan_rose CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1325 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188059 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 888963359b..a5bd74f920 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/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(*it), LCtx); - if (dyn_cast_or_null(V.getAsRegion())) - V = UnknownVal(); vals = getBasicVals().consVals(V, vals); } diff --git a/test/Analysis/temporaries.cpp b/test/Analysis/temporaries.cpp index ea4abb2d84..5e1771cc44 100644 --- a/test/Analysis/temporaries.cpp +++ b/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}} + } +}