]> granicus.if.org Git - clang/commitdiff
[CFG] [analyzer] pr41142: C++17: Skip transparent InitListExprs in ExprEngine.
authorArtem Dergachev <artem.dergachev@gmail.com>
Tue, 26 Mar 2019 00:36:53 +0000 (00:36 +0000)
committerArtem Dergachev <artem.dergachev@gmail.com>
Tue, 26 Mar 2019 00:36:53 +0000 (00:36 +0000)
r356634 didn't fix all the problems caused by r356222 - even though simple
constructors involving transparent init-list expressions are now evaluated
precisely, many more complicated constructors aren't, for other reasons.

The attached test case is an example of a constructor that will never be
evaluated precisely - simply because there isn't a constructor there (instead,
the program invokes run-time undefined behavior by returning without a return
statement that should have constructed the return value).

Fix another part of the problem for such situations: evaluate transparent
init-list expressions transparently, so that to avoid creating ill-formed
"transparent" nonloc::CompoundVals.

Differential Revision: https://reviews.llvm.org/D59622

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356969 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/ExprEngineC.cpp
test/Analysis/initializer.cpp

index 6c1eda622c83b3767c341cf2982df5384bb826bf..11a3befcb1d99bca7b5f12def838f21ccc9c6441 100644 (file)
@@ -704,7 +704,7 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
   QualType T = getContext().getCanonicalType(IE->getType());
   unsigned NumInitElements = IE->getNumInits();
 
-  if (!IE->isGLValue() &&
+  if (!IE->isGLValue() && !IE->isTransparent() &&
       (T->isArrayType() || T->isRecordType() || T->isVectorType() ||
        T->isAnyComplexType())) {
     llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
index 5853f3aed565509c0f2ee40357748084c1a17bf3..56b0a09d47455ac9b88b7eb9007d93197502bf13 100644 (file)
@@ -1,7 +1,17 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++17 -DCPLUSPLUS17 -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++17 -DCPLUSPLUS17 -DTEST_INLINABLE_ALLOCATORS -verify %s
+// RUN: %clang_analyze_cc1 -w -verify %s\
+// RUN:   -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\
+// RUN:   -analyzer-checker=debug.ExprInspection -std=c++11
+// RUN: %clang_analyze_cc1 -w -verify %s\
+// RUN:   -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\
+// RUN:   -analyzer-checker=debug.ExprInspection -std=c++17
+// RUN: %clang_analyze_cc1 -w -verify %s\
+// RUN:   -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\
+// RUN:   -analyzer-checker=debug.ExprInspection -std=c++11\
+// RUN:   -DTEST_INLINABLE_ALLOCATORS
+// RUN: %clang_analyze_cc1 -w -verify %s\
+// RUN:   -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\
+// RUN:   -analyzer-checker=debug.ExprInspection -std=c++17\
+// RUN:   -DTEST_INLINABLE_ALLOCATORS
 
 void clang_analyzer_eval(bool);
 
@@ -232,7 +242,7 @@ void foo() {
 
   D d = {}; // no-crash
 
-#ifdef CPLUSPLUS17
+#if __cplusplus >= 201703L
   C cd = {{}}; // no-crash
   const C &cdl = {{}}; // no-crash
   C &&cdr = {{}}; // no-crash
@@ -260,4 +270,8 @@ C coo();
 void foo2() {
   C c { coo() }; // no-crash
 }
+
+B foo_recursive() {
+  B b { foo_recursive() };
+}
 } // namespace CXX17_transparent_init_list_exprs