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];