On 9/1/20 12:10 PM, Marek Polacek wrote:
Currently, we allow new char[]{"foo"}, but not new char[4]{"foo"}.
We should accept the latter too: [dcl.init.list]p3.3 says to treat
this as [dcl.init.string].
We were rejecting this code because we never called reshape_init before
the digest_init in build_new_1. reshape_init handles [dcl.init.string]
by unwrapping the STRING_CST from its enclosing { }, and digest_init
assumes that reshape_init has been called for aggregates anyway, and an
array is an aggregate.
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
gcc/cp/ChangeLog:
PR c++/77841
* init.c (build_new_1): Call reshape_init.
gcc/testsuite/ChangeLog:
PR c++/77841
* g++.dg/cpp0x/initlist-new4.C: New test.
---
gcc/cp/init.c | 6 ++++++
gcc/testsuite/g++.dg/cpp0x/initlist-new4.C | 6 ++++++
2 files changed, 12 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist-new4.C
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 360ab8c0b52..d4540db3605 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3575,6 +3575,12 @@ build_new_1 (vec<tree, va_gc> **placement, tree type,
tree nelts,
/* We'll check the length at runtime. */
domain = NULL_TREE;
arraytype = build_cplus_array_type (type, domain);
+ /* If we have new char[4]{"foo"}, we have to reshape
+ so that the STRING_CST isn't wrapped in { }. */
+ vecinit = reshape_init (arraytype, vecinit, complain);
+ /* The middle end doesn't cope with the location wrapper
+ around a STRING_CST. */
+ STRIP_ANY_LOCATION_WRAPPER (vecinit);
vecinit = digest_init (arraytype, vecinit, complain);
}
This is OK, but now I wonder why your earlier addition,
/* This handles code like new char[]{"foo"}. */
else if (len == 1
&& char_type_p (TYPE_MAIN_VARIANT (type))
&& TREE_CODE (tree_strip_any_location_wrapper ((**init)[0]))
== STRING_CST)
{
vecinit = (**init)[0];
STRIP_ANY_LOCATION_WRAPPER (vecinit);
}
isn't handled by the block you're changing in this patch. Why isn't
DIRECT_LIST_INIT_P true for new char[]{"foo"}?
Jason