aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2020-02-24 09:19:01 -0500
committerMarek Polacek <polacek@redhat.com>2020-02-26 10:01:51 -0500
commitd6ff22074126d38829f25981de9d6940cd2a234c (patch)
tree3667d1402d01145c09dccff8621a14b750f25fd5
parent759bd406a2b900dd323571c3855a64f885e6b3b7 (diff)
downloadgcc-d6ff22074126d38829f25981de9d6940cd2a234c.zip
gcc-d6ff22074126d38829f25981de9d6940cd2a234c.tar.gz
gcc-d6ff22074126d38829f25981de9d6940cd2a234c.tar.bz2
c++: Fix ICE with constexpr init and [[no_unique_address]] [PR93803]
Here we crash when constexpr-initializing a class member of empty class type with [[no_unique_address]]. Without the attribute we would have a ctor (that initializes bar) of the form { .D.2173 = { .x = {} } } but with the attribute reduced_constant_expression_p gets { .x = {} } That means that "idx != field" is true for the latter and we see that foo, the base class of bar, is an empty class, so we want to look at the next initializable field (since empty class fields may not have an initializer). But in this case there are no more, therefore accessing DECL_CHAIN (field) crashes. Long story short, we need to avoid a crash on a null field when we're initializing a class that only contains an empty base class. While poking into this I discovered c++/93898, but that's a different problem. 2020-02-26 Marek Polacek <polacek@redhat.com> PR c++/93803 - ICE with constexpr init and [[no_unique_address]]. * constexpr.c (reduced_constant_expression_p): Don't crash on a null field. * g++.dg/cpp2a/constexpr-init16.C: New test. * g++.dg/cpp2a/constexpr-init17.C: New test.
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/constexpr.c16
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-init16.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-init17.C15
5 files changed, 49 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0cc971d..1489453 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2020-02-26 Marek Polacek <polacek@redhat.com>
+
+ PR c++/93803 - ICE with constexpr init and [[no_unique_address]].
+ * constexpr.c (reduced_constant_expression_p): Don't crash on a null
+ field.
+
2020-02-24 Martin Sebor <msebor@redhat.com>
PR c++/93804
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 128f760..3da1609 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -2603,16 +2603,14 @@ reduced_constant_expression_p (tree t)
element. */
if (!reduced_constant_expression_p (val))
return false;
+ /* Empty class field may or may not have an initializer. */
+ for (; field && idx != field;
+ field = next_initializable_field (DECL_CHAIN (field)))
+ if (!is_really_empty_class (TREE_TYPE (field),
+ /*ignore_vptr*/false))
+ return false;
if (field)
- {
- /* Empty class field may or may not have an initializer. */
- for (; idx != field;
- field = next_initializable_field (DECL_CHAIN (field)))
- if (!is_really_empty_class (TREE_TYPE (field),
- /*ignore_vptr*/false))
- return false;
- field = next_initializable_field (DECL_CHAIN (field));
- }
+ field = next_initializable_field (DECL_CHAIN (field));
}
/* There could be a non-empty field at the end. */
for (; field; field = next_initializable_field (DECL_CHAIN (field)))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index aa5d41e..4f46c38 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2020-02-26 Marek Polacek <polacek@redhat.com>
+
+ PR c++/93803 - ICE with constexpr init and [[no_unique_address]].
+ * g++.dg/cpp2a/constexpr-init16.C: New test.
+ * g++.dg/cpp2a/constexpr-init17.C: New test.
+
2020-02-26 Richard Sandiford <richard.sandiford@arm.com>
PR middle-end/93843
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-init16.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-init16.C
new file mode 100644
index 0000000..16db297
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-init16.C
@@ -0,0 +1,15 @@
+// PR c++/93803 - ICE with constexpr init and [[no_unique_address]].
+// { dg-do compile { target c++2a } }
+
+struct empty { };
+
+struct foo {
+ [[no_unique_address]] empty x;
+ constexpr foo() : x{} { }
+};
+
+struct bar : foo {
+ using foo::foo;
+};
+
+constexpr bar a{};
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-init17.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-init17.C
new file mode 100644
index 0000000..34d9fe5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-init17.C
@@ -0,0 +1,15 @@
+// PR c++/93803 - ICE with constexpr init and [[no_unique_address]].
+// { dg-do compile { target c++2a } }
+
+struct empty { };
+
+struct foo {
+ [[no_unique_address]] empty x, x2, x3;
+ constexpr foo() : x{}, x2{} { }
+};
+
+struct bar : foo {
+ using foo::foo;
+};
+
+constexpr bar a{};