[Bug c++/124531] [15 regression] ICE on char[] with large initializer list
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Jun 1 20:53:03 GMT 2026
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124531
--- Comment #8 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-15 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:
https://gcc.gnu.org/g:87e1a06d54aea9402c4d72d95c3adf8168c35267
commit r15-11211-g87e1a06d54aea9402c4d72d95c3adf8168c35267
Author: Jakub Jelinek <jakub@redhat.com>
Date: Fri Apr 3 10:18:25 2026 +0200
c++: Handle RAW_DATA_CST and RANGE_EXPR in build_vec_init [PR124531]
The following testcases show two bugs in build_vec_init, one
introduced with either since my r15-5958 (when using #embed) or
my r15-6339 (when not using it but large init transformed into
RAW_DATA_CST), problem that the FOR_EACH_CONSTRUCTOR_ELT loop
in build_vec_init doesn't handle RAW_DATA_CST, and another since
Marek's r15-7810 which has added limited RANGE_EXPR support to that loop,
but only changed the num_initialized_elts value computation and
has not actually also added a runtime loop over the range to initialize
multiple elements to the same value. The lack of RAW_DATA_CST handling
causes ICEs (during expansion or later on), while the lack of proper
RANGE_EXPR handling causes wrong-code.
The following patch attempts to fix both.
RAW_DATA_CST has 2 separate variants of handling it, one is when
the types match (digested is true) and it is char/signed char/unsigned
char/std::byte array, in that case (especially if it is huge initializer,
but RAW_DATA_CST already implies 62+ elements) it emits a setting of
MEM_REF with ARRAY_TYPE for the RAW_DATA_LENGTH bytes to a CONSTRUCTOR
with the RAW_DATA_CST in it which gimplifier handles (but of course for
try_const const_vec it uses the RAW_DATA_CST directly).
The second variant is for other types or non-digested one, in that case
RAW_DATA_CST is peeled appart into individual INTEGER_CSTs.
As for RANGE_EXPR, for try_const const_vec it uses the RANGE_EXPR field
as before, but for the runtime code it puts the
one_init/base increment/iterator decrement stmts into a loop which iterates
range_expr_nelts times.
The reason for the first hunk is to optimize the CONSTRUCTOR from what
the preprocessor emits, i.e.
CPP_NUMBER CPP_COMMA CPP_EMBED CPP_COMMA CPP_NUMBER
turned into
INTEGER_CST RAW_DATA_CST INTEGER_CST
into just RAW_DATA_CST covering also the first and last number.
I'm worried about braced_lists_to_strings transformation to STRING_CST
when try_const though, I think it isn't handled right now, so the code
ignores STRING_CST return.
2026-04-03 Jakub Jelinek <jakub@redhat.com>
PR c++/124531
* init.cc (build_vec_init): Call braced_lists_to_strings for
array CONSTRUCTORs. Handle RAW_DATA_CST and handle RANGE_EXPR
correctly.
* g++.dg/cpp/embed-29.C: New test.
* g++.dg/cpp0x/pr124531.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
(cherry picked from commit 0229b5b3da003647f1dfd0941f8b8af762a69f1d)
More information about the Gcc-bugs
mailing list