]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Fix constexpr vs. omitted aggregate init.
authorJason Merrill <jason@redhat.com>
Wed, 26 Feb 2020 18:03:23 +0000 (13:03 -0500)
committerJason Merrill <jason@redhat.com>
Wed, 26 Feb 2020 19:09:03 +0000 (14:09 -0500)
Value-initialization is importantly different from {}-initialization for
this testcase, where the former calls the deleted S constructor and the
latter initializes S happily.

gcc/cp/ChangeLog
2020-02-26  Jason Merrill  <jason@redhat.com>

PR c++/90951
* constexpr.c (cxx_eval_array_reference): {}-initialize missing
elements instead of value-initializing them.

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp0x/constexpr-array24.C [new file with mode: 0644]

index 8c4d662d7ec959b1791685909cc439526f617d37..2b83f4da57834b02797233e880a440a735c412ad 100644 (file)
@@ -1,3 +1,9 @@
+2020-02-26  Jason Merrill  <jason@redhat.com>
+
+       PR c++/90951
+       * constexpr.c (cxx_eval_array_reference): {}-initialize missing
+       elements instead of value-initializing them.
+
 2020-02-26  Jason Merrill  <jason@redhat.com>
 
        PR c++/93140
index a7728285dc5103bdcec15947c6e7d2e3134e0301..bc2476f94f924c0d4ec7359f061b4a91a0d49c2e 100644 (file)
@@ -2662,8 +2662,16 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
     }
 
   /* If it's within the array bounds but doesn't have an explicit
-     initializer, it's value-initialized.  */
-  tree val = build_value_init (elem_type, tf_warning_or_error);
+     initializer, it's initialized from {}.  But use build_value_init
+     directly for non-aggregates to avoid creating a garbage CONSTRUCTOR.  */
+  tree val;
+  if (CP_AGGREGATE_TYPE_P (elem_type))
+    {
+      tree empty_ctor = build_constructor (init_list_type_node, NULL);
+      val = digest_init (elem_type, empty_ctor, tf_warning_or_error);
+    }
+  else
+    val = build_value_init (elem_type, tf_warning_or_error);
   return cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
                                       overflow_p);
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array24.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array24.C
new file mode 100644 (file)
index 0000000..5389698
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/90951
+// { dg-do compile { target c++11 } }
+
+#define assert(expr) static_assert (expr, #expr)
+
+struct S { const char a[2]; };
+
+constexpr struct S a[1][1][1] = { };
+
+assert ('\0' == *a[0][0][0].a);