NoQ created this revision. NoQ added reviewers: dcoughlin, xazax.hun, a_sidorin, rnkovacs, mikhail.ramalho, Szelethus, baloghadamsoftware, Charusso. Herald added subscribers: cfe-commits, jdoerfert, dkrupp, donat.nagy, a.sidorin, szepet. Herald added a project: clang. NoQ added a parent revision: D59573: [analyzer] C++17: PR41142: Ignore transparent InitListExprs when finding construction contexts..
When evaluating a transparent `InitListExpr`, eg. `{{{{{{X}}}}}}}` (when it's equivalent to a plain `X`), don't try to think of it as of a compound value of type `X` that contains an `X` - just think of it as of `X` itself. I hope this should take care of the remaining problems that i identified in D59573 <https://reviews.llvm.org/D59573>, for which this patch is a follow-up. On second thought, there shouldn't be any correctness problems because of multiple inheritance. If there's just one object in the initializer list, it's always at offset 0. So i don't think there are going to be any other changes in the actual behavior - just less crashes. There's a chance that i missed other cases when a non-aggregate would be accidentally represented as a compound value, but i'm not immediately aware of such cases. Add the original test from https://bugs.llvm.org/show_bug.cgi?id=41142 (the top-level recursive call would now evaluate into `Unknown` rather than `compoundVal{Unknown}` - which is still worse than the correct `Undefined` value, but it's at least not crashing). Btw, once we make sure it's `Undefined`, we should probably also add a path note indicating that the function returns a garbage value because there's no return statement in it on the current execution path. Repository: rC Clang https://reviews.llvm.org/D59622 Files: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp clang/test/Analysis/initializer.cpp Index: clang/test/Analysis/initializer.cpp =================================================================== --- clang/test/Analysis/initializer.cpp +++ clang/test/Analysis/initializer.cpp @@ -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 @@ 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 @@ void foo2() { C c { coo() }; // no-crash } + +B foo_recursive() { + B b { foo_recursive() }; +} } // namespace CXX17_transparent_init_list_exprs Index: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -702,7 +702,7 @@ 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: clang/test/Analysis/initializer.cpp =================================================================== --- clang/test/Analysis/initializer.cpp +++ clang/test/Analysis/initializer.cpp @@ -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 @@ 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 @@ void foo2() { C c { coo() }; // no-crash } + +B foo_recursive() { + B b { foo_recursive() }; +} } // namespace CXX17_transparent_init_list_exprs Index: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -702,7 +702,7 @@ 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();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits