summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis/initializer.cpp
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2017-12-20 00:40:38 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2017-12-20 00:40:38 +0000
commite8ba3ec4537eecd7d2947e89a35338f884bba96c (patch)
tree8e032b4bf69c64845a7516071911e3b8c588c415 /clang/test/Analysis/initializer.cpp
parent83b162269f86daf085a9fc8dfe029bdf64cd6b06 (diff)
downloadbcm5719-llvm-e8ba3ec4537eecd7d2947e89a35338f884bba96c.tar.gz
bcm5719-llvm-e8ba3ec4537eecd7d2947e89a35338f884bba96c.zip
[analyzer] Fix a crash during C++17 aggregate construction of base objects.
Since C++17, classes that have base classes can potentially be initialized as aggregates. Trying to construct such objects through brace initialization was causing the analyzer to crash when the base class has a non-trivial constructor, while figuring target region for the base class constructor, because the parent stack frame didn't contain the constructor of the subclass, because there is no constructor for subclass, merely aggregate initialization. This patch avoids the crash, but doesn't provide the actually correct region for the constructor, which still remains to be fixed. Instead, construction goes into a fake temporary region which would be immediately discarded. Similar extremely conservative approach is used for other cases in which the logic for finding the target region is not yet implemented, including aggregate initialization with fields instead of base-regions (which is not C++17-specific but also never worked, just didn't crash). Differential revision: https://reviews.llvm.org/D40841 rdar://problem/35441058 llvm-svn: 321128
Diffstat (limited to 'clang/test/Analysis/initializer.cpp')
-rw-r--r--clang/test/Analysis/initializer.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/clang/test/Analysis/initializer.cpp b/clang/test/Analysis/initializer.cpp
index 6359b93d0a2..55f0a895028 100644
--- a/clang/test/Analysis/initializer.cpp
+++ b/clang/test/Analysis/initializer.cpp
@@ -1,4 +1,5 @@
// 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
void clang_analyzer_eval(bool);
@@ -224,3 +225,42 @@ void testPassListsWithExplicitConstructors() {
(void)(std::initializer_list<int>){12}; // no-crash
}
}
+
+namespace CXX17_aggregate_construction {
+struct A {
+ A();
+};
+
+struct B: public A {
+};
+
+struct C: public B {
+};
+
+struct D: public virtual A {
+};
+
+// In C++17, classes B and C are aggregates, so they will be constructed
+// without actually calling their trivial constructor. Used to crash.
+void foo() {
+ B b = {}; // no-crash
+ const B &bl = {}; // no-crash
+ B &&br = {}; // no-crash
+
+ C c = {}; // no-crash
+ const C &cl = {}; // no-crash
+ C &&cr = {}; // no-crash
+
+ D d = {}; // no-crash
+
+#ifdef CPLUSPLUS17
+ C cd = {{}}; // no-crash
+ const C &cdl = {{}}; // no-crash
+ C &&cdr = {{}}; // no-crash
+
+ const B &bll = {{}}; // no-crash
+ const B &bcl = C({{}}); // no-crash
+ B &&bcr = C({{}}); // no-crash
+#endif
+}
+}
OpenPOWER on IntegriCloud