[CFG] [analyzer] pr41142: C++17: Skip transparent InitListExprs in constructors.
When searching for construction contexts, i.e. figuring out which statements define the object that is constructed by each construct-expression, ignore transparent init-list expressions because they don't add anything to the context. This allows the Static Analyzer to model construction, destruction, materialization, lifetime extension correctly in more cases. Also fixes a crash caused by incorrectly evaluating initial values of variables initialized with such expressions. Differential Revision: https://reviews.llvm.org/D59573 llvm-svn: 356634
This commit is contained in:
parent
f1d87f8b4c
commit
aa40315c69
|
@ -1378,6 +1378,15 @@ void CFGBuilder::findConstructionContexts(
|
|||
findConstructionContexts(Layer, CO->getRHS());
|
||||
break;
|
||||
}
|
||||
case Stmt::InitListExprClass: {
|
||||
auto *ILE = cast<InitListExpr>(Child);
|
||||
if (ILE->isTransparent()) {
|
||||
findConstructionContexts(Layer, ILE->getInit(0));
|
||||
break;
|
||||
}
|
||||
// TODO: Handle other cases. For now, fail to find construction contexts.
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1043,3 +1043,23 @@ void testCrashOnVariadicArgument() {
|
|||
C c(variadic(0 ? c : 0)); // no-crash
|
||||
}
|
||||
} // namespace variadic_function_arguments
|
||||
|
||||
// CHECK: void testTransparentInitListExprs()
|
||||
// CHECK: [B1]
|
||||
// CHECK-NEXT: 1: getC
|
||||
// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class transparent_init_list_exprs::C (*)(void))
|
||||
// CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5])
|
||||
// CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4])
|
||||
// CXX11-NEXT: 4: [B1.3]
|
||||
// CXX11-NEXT: 5: {[B1.4]} (CXXConstructExpr, [B1.6], class transparent_init_list_exprs::C)
|
||||
// CXX11-NEXT: 6: transparent_init_list_exprs::C c{getC()};
|
||||
// CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5])
|
||||
// CXX17-NEXT: 4: {[B1.3]}
|
||||
// CXX17-NEXT: 5: transparent_init_list_exprs::C c{getC()};
|
||||
namespace transparent_init_list_exprs {
|
||||
class C {};
|
||||
C getC();
|
||||
void testTransparentInitListExprs() {
|
||||
C c{getC()};
|
||||
}
|
||||
} // namespace transparent_init_list_exprs
|
||||
|
|
|
@ -242,4 +242,22 @@ void foo() {
|
|||
B &&bcr = C({{}}); // no-crash
|
||||
#endif
|
||||
}
|
||||
} // namespace CXX17_aggregate_construction
|
||||
|
||||
namespace CXX17_transparent_init_list_exprs {
|
||||
class A {};
|
||||
|
||||
class B: private A {};
|
||||
|
||||
B boo();
|
||||
void foo1() {
|
||||
B b { boo() }; // no-crash
|
||||
}
|
||||
|
||||
class C: virtual public A {};
|
||||
|
||||
C coo();
|
||||
void foo2() {
|
||||
C c { coo() }; // no-crash
|
||||
}
|
||||
} // namespace CXX17_transparent_init_list_exprs
|
||||
|
|
Loading…
Reference in New Issue