Skip to content

Commit

Permalink
[CFG] [analyzer] pr41142: C++17: Skip transparent InitListExprs in co…
Browse files Browse the repository at this point in the history
…nstructors.

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
  • Loading branch information
haoNoQ committed Mar 21, 2019
1 parent f1d87f8 commit aa40315
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
9 changes: 9 additions & 0 deletions clang/lib/Analysis/CFG.cpp
Expand Up @@ -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;
}
Expand Down
20 changes: 20 additions & 0 deletions clang/test/Analysis/cfg-rich-constructors.cpp
Expand Up @@ -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
18 changes: 18 additions & 0 deletions clang/test/Analysis/initializer.cpp
Expand Up @@ -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

0 comments on commit aa40315

Please sign in to comment.