On 6/29/21 2:25 PM, Patrick Palka wrote:
Here the initializer for 'x' is represented as an empty CONSTRUCTOR
due to its empty element type.  So during constexpr evaluation of the
ARRAY_REF 'x[0]', we end up trying to lazily value initialize the
omitted element at index 0, which fails because the element type is not
default initializable.

This patch makes cxx_eval_array_reference handle specially the case
where the element type is empty.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

OK.

        PR c++/101194

gcc/cp/ChangeLog:

        * constexpr.c (cxx_eval_array_reference): When the element type
        is empty, just return an empty CONSTRUCTOR for an omitted
        element instead of attempting value initialization.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp0x/constexpr-empty16.C: New test.
---
  gcc/cp/constexpr.c                             |  4 +++-
  gcc/testsuite/g++.dg/cpp0x/constexpr-empty16.C | 10 ++++++++++
  2 files changed, 13 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-empty16.C

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 4cd9db33a1a..39787f3f5d5 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -3845,7 +3845,9 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree 
t,
       directly for non-aggregates to avoid creating a garbage CONSTRUCTOR.  */
    tree val;
    constexpr_ctx new_ctx;
-  if (CP_AGGREGATE_TYPE_P (elem_type))
+  if (is_really_empty_class (elem_type, /*ignore_vptr*/false))
+    return build_constructor (elem_type, NULL);
+  else 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);
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-empty16.C 
b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty16.C
new file mode 100644
index 00000000000..79be244a1d0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty16.C
@@ -0,0 +1,10 @@
+// PR c++/101194
+// { dg-do compile { target c++11 } }
+
+struct nodefault {
+  constexpr nodefault(int) { }
+};
+
+constexpr nodefault x[1] = { nodefault{0} };
+
+constexpr nodefault y = x[0];


Reply via email to