* [PATCH] c++: Fix ICEs with large initializer lists or ones including #embed [PR118124]
@ 2024-12-19 16:07 Jakub Jelinek
2024-12-19 16:52 ` Jason Merrill
0 siblings, 1 reply; 7+ messages in thread
From: Jakub Jelinek @ 2024-12-19 16:07 UTC (permalink / raw)
To: Jason Merrill; +Cc: gcc-patches
Hi!
The following testcases ICE due to RAW_DATA_CST not being handled where it
should be during ck_list conversions.
The last 2 testcases started ICEing with r15-6339 committed yesterday
(speedup of large initializers), the first two already with r15-5958
(#embed optimization for C++).
For conversion to initializer_list<unsigned char> or char/signed char
we can optimize and keep RAW_DATA_CST with adjusted type if we report
narrowing errors if needed, for others this converts each element
separately.
Ok for trunk if this passes bootstrap/regtest? Wouldn't like to
leave this broken over Christmas holidays.
2024-12-19 Jakub Jelinek <jakub@redhat.com>
PR c++/118124
* call.cc (convert_like_internal): Handle RAW_DATA_CST in
ck_list handling. Formatting fixes.
* g++.dg/cpp/embed-15.C: New test.
* g++.dg/cpp/embed-16.C: New test.
* g++.dg/cpp0x/initlist-opt3.C: New test.
* g++.dg/cpp0x/initlist-opt4.C: New test.
--- gcc/cp/call.cc.jj 2024-12-11 17:27:52.481221310 +0100
+++ gcc/cp/call.cc 2024-12-19 16:10:12.977071898 +0100
@@ -8766,8 +8766,8 @@ convert_like_internal (conversion *convs
if (tree init = maybe_init_list_as_array (elttype, expr))
{
- elttype = cp_build_qualified_type
- (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST);
+ elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype)
+ | TYPE_QUAL_CONST);
array = build_array_of_n_type (elttype, len);
array = build_vec_init_expr (array, init, complain);
array = get_target_expr (array);
@@ -8775,13 +8775,75 @@ convert_like_internal (conversion *convs
}
else if (len)
{
- tree val; unsigned ix;
-
+ tree val;
+ unsigned ix;
tree new_ctor = build_constructor (init_list_type_node, NULL);
/* Convert all the elements. */
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val)
{
+ if (TREE_CODE (val) == RAW_DATA_CST)
+ {
+ tree elt_type;
+ conversion *next;
+ if (convs->u.list[ix]->kind == ck_std
+ && (elt_type = convs->u.list[ix]->type)
+ && (TREE_CODE (elt_type) == INTEGER_TYPE
+ || is_byte_access_type (elt_type))
+ && TYPE_PRECISION (elt_type) == CHAR_BIT
+ && (next = next_conversion (convs->u.list[ix]))
+ && next->kind == ck_identity)
+ {
+ if (!TYPE_UNSIGNED (elt_type)
+ && (complain & tf_warning)
+ && (TYPE_UNSIGNED (TREE_TYPE (val))
+ || (TYPE_PRECISION (TREE_TYPE (val))
+ > CHAR_BIT)))
+ for (int i = 0; i < RAW_DATA_LENGTH (val); ++i)
+ if (RAW_DATA_SCHAR_ELT (val, i) < 0)
+ {
+ location_t loc
+ = cp_expr_loc_or_input_loc (val);
+ int savederrorcount = errorcount;
+ permerror_opt (loc, OPT_Wnarrowing,
+ "narrowing conversion of %qd "
+ "from %qH to %qI",
+ RAW_DATA_UCHAR_ELT (val, i),
+ TREE_TYPE (val), elt_type);
+ if (errorcount != savederrorcount)
+ return error_mark_node;
+ }
+ tree sub = copy_node (val);
+ TREE_TYPE (sub) = elt_type;
+ CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor),
+ NULL_TREE, sub);
+ }
+ else
+ {
+ for (int i = 0; i < RAW_DATA_LENGTH (val); ++i)
+ {
+ tree elt
+ = build_int_cst (TREE_TYPE (val),
+ RAW_DATA_UCHAR_ELT (val, i));
+ tree sub
+ = convert_like (convs->u.list[ix], elt,
+ fn, argnum, false, false,
+ /*nested_p=*/true, complain);
+ if (sub == error_mark_node)
+ return sub;
+ if (!check_narrowing (TREE_TYPE (sub), elt,
+ complain))
+ return error_mark_node;
+ tree nc = new_ctor;
+ CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (nc),
+ NULL_TREE, sub);
+ if (!TREE_CONSTANT (sub))
+ TREE_CONSTANT (new_ctor) = false;
+ }
+ }
+ len += RAW_DATA_LENGTH (val) - 1;
+ continue;
+ }
tree sub = convert_like (convs->u.list[ix], val, fn,
argnum, false, false,
/*nested_p=*/true, complain);
@@ -8796,8 +8858,8 @@ convert_like_internal (conversion *convs
TREE_CONSTANT (new_ctor) = false;
}
/* Build up the array. */
- elttype = cp_build_qualified_type
- (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST);
+ elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype)
+ | TYPE_QUAL_CONST);
array = build_array_of_n_type (elttype, len);
array = finish_compound_literal (array, new_ctor, complain);
/* This is dubious now, should be blessed by P2752. */
--- gcc/testsuite/g++.dg/cpp/embed-15.C.jj 2024-12-19 15:07:28.564605983 +0100
+++ gcc/testsuite/g++.dg/cpp/embed-15.C 2024-12-19 15:08:14.194998077 +0100
@@ -0,0 +1,35 @@
+// PR c++/118124
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2" }
+
+namespace std {
+template <class T> struct initializer_list {
+private:
+ const T *_M_array;
+ __SIZE_TYPE__ _M_len;
+};
+}
+struct A {
+ A (std::initializer_list<char>);
+};
+A a {
+#embed __FILE__
+};
+struct B {
+ B (std::initializer_list<unsigned char>);
+};
+B b {
+#embed __FILE__
+};
+struct C {
+ C (std::initializer_list<int>);
+};
+C c {
+#embed __FILE__
+};
+struct D {
+ D (std::initializer_list<float>);
+};
+D d {
+#embed __FILE__
+};
--- gcc/testsuite/g++.dg/cpp/embed-16.C.jj 2024-12-19 15:09:20.929109016 +0100
+++ gcc/testsuite/g++.dg/cpp/embed-16.C 2024-12-19 15:11:12.811618467 +0100
@@ -0,0 +1,18 @@
+// PR c++/118124
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2" }
+// non-ASCII chars here: áéí
+
+namespace std {
+template <class T> struct initializer_list {
+private:
+ const T *_M_array;
+ __SIZE_TYPE__ _M_len;
+};
+}
+struct A {
+ A (std::initializer_list<signed char>);
+};
+A a {
+#embed __FILE__
+}; // { dg-error "narrowing conversion of '\[0-9]*' from 'int' to 'signed char'" }
--- gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C.jj 2024-12-19 14:52:17.389013179 +0100
+++ gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C 2024-12-19 15:06:28.652404163 +0100
@@ -0,0 +1,47 @@
+// PR c++/118124
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2" }
+
+namespace std {
+template <class T> struct initializer_list {
+private:
+ const T *_M_array;
+ __SIZE_TYPE__ _M_len;
+};
+}
+struct A {
+ A (std::initializer_list<char>);
+};
+A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 };
+struct B {
+ B (std::initializer_list<unsigned char>);
+};
+B b { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 };
+struct C {
+ C (std::initializer_list<int>);
+};
+C c { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 };
+struct D {
+ D (std::initializer_list<float>);
+};
+D d { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 };
--- gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C.jj 2024-12-19 14:52:46.517612306 +0100
+++ gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C 2024-12-19 15:06:52.513086275 +0100
@@ -0,0 +1,20 @@
+// PR c++/118124
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2" }
+
+namespace std {
+template <class T> struct initializer_list {
+private:
+ const T *_M_array;
+ __SIZE_TYPE__ _M_len;
+};
+}
+struct A {
+ A (std::initializer_list<signed char>);
+};
+A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 209, 0, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; // { dg-error "narrowing conversion of '209' from 'int' to 'signed char'" }
Jakub
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] c++: Fix ICEs with large initializer lists or ones including #embed [PR118124] 2024-12-19 16:07 [PATCH] c++: Fix ICEs with large initializer lists or ones including #embed [PR118124] Jakub Jelinek @ 2024-12-19 16:52 ` Jason Merrill 2024-12-19 18:01 ` [PATCH] c++, v2: " Jakub Jelinek 0 siblings, 1 reply; 7+ messages in thread From: Jason Merrill @ 2024-12-19 16:52 UTC (permalink / raw) To: Jakub Jelinek; +Cc: gcc-patches On 12/19/24 11:07 AM, Jakub Jelinek wrote: > Hi! > > The following testcases ICE due to RAW_DATA_CST not being handled where it > should be during ck_list conversions. > > The last 2 testcases started ICEing with r15-6339 committed yesterday > (speedup of large initializers), the first two already with r15-5958 > (#embed optimization for C++). > > For conversion to initializer_list<unsigned char> or char/signed char > we can optimize and keep RAW_DATA_CST with adjusted type if we report > narrowing errors if needed, for others this converts each element > separately. Please add this paragraph as a comment. > Ok for trunk if this passes bootstrap/regtest? Wouldn't like to > leave this broken over Christmas holidays. > > 2024-12-19 Jakub Jelinek <jakub@redhat.com> > > PR c++/118124 > * call.cc (convert_like_internal): Handle RAW_DATA_CST in > ck_list handling. Formatting fixes. > > * g++.dg/cpp/embed-15.C: New test. > * g++.dg/cpp/embed-16.C: New test. > * g++.dg/cpp0x/initlist-opt3.C: New test. > * g++.dg/cpp0x/initlist-opt4.C: New test. > > --- gcc/cp/call.cc.jj 2024-12-11 17:27:52.481221310 +0100 > +++ gcc/cp/call.cc 2024-12-19 16:10:12.977071898 +0100 > @@ -8766,8 +8766,8 @@ convert_like_internal (conversion *convs > > if (tree init = maybe_init_list_as_array (elttype, expr)) > { > - elttype = cp_build_qualified_type > - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); > + elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype) > + | TYPE_QUAL_CONST); > array = build_array_of_n_type (elttype, len); > array = build_vec_init_expr (array, init, complain); > array = get_target_expr (array); > @@ -8775,13 +8775,75 @@ convert_like_internal (conversion *convs > } > else if (len) > { > - tree val; unsigned ix; > - > + tree val; > + unsigned ix; > tree new_ctor = build_constructor (init_list_type_node, NULL); > > /* Convert all the elements. */ > FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val) > { > + if (TREE_CODE (val) == RAW_DATA_CST) > + { > + tree elt_type; > + conversion *next; > + if (convs->u.list[ix]->kind == ck_std > + && (elt_type = convs->u.list[ix]->type) > + && (TREE_CODE (elt_type) == INTEGER_TYPE > + || is_byte_access_type (elt_type)) > + && TYPE_PRECISION (elt_type) == CHAR_BIT > + && (next = next_conversion (convs->u.list[ix])) > + && next->kind == ck_identity) > + { > + if (!TYPE_UNSIGNED (elt_type) > + && (complain & tf_warning) We shouldn't check tf_warning here. > + && (TYPE_UNSIGNED (TREE_TYPE (val)) > + || (TYPE_PRECISION (TREE_TYPE (val)) > + > CHAR_BIT))) > + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) > + if (RAW_DATA_SCHAR_ELT (val, i) < 0) > + { Instead, check tf_warning_or_error here, and return error_mark_node if it's not set. > + location_t loc > + = cp_expr_loc_or_input_loc (val); > + int savederrorcount = errorcount; > + permerror_opt (loc, OPT_Wnarrowing, > + "narrowing conversion of %qd " > + "from %qH to %qI", > + RAW_DATA_UCHAR_ELT (val, i), > + TREE_TYPE (val), elt_type); > + if (errorcount != savederrorcount) > + return error_mark_node; > + } > + tree sub = copy_node (val); > + TREE_TYPE (sub) = elt_type; > + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), > + NULL_TREE, sub); > + } > + else > + { > + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) > + { > + tree elt > + = build_int_cst (TREE_TYPE (val), > + RAW_DATA_UCHAR_ELT (val, i)); > + tree sub > + = convert_like (convs->u.list[ix], elt, > + fn, argnum, false, false, > + /*nested_p=*/true, complain); > + if (sub == error_mark_node) > + return sub; > + if (!check_narrowing (TREE_TYPE (sub), elt, > + complain)) > + return error_mark_node; > + tree nc = new_ctor; > + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (nc), > + NULL_TREE, sub); > + if (!TREE_CONSTANT (sub)) > + TREE_CONSTANT (new_ctor) = false; > + } > + } > + len += RAW_DATA_LENGTH (val) - 1; > + continue; > + } > tree sub = convert_like (convs->u.list[ix], val, fn, > argnum, false, false, > /*nested_p=*/true, complain); > @@ -8796,8 +8858,8 @@ convert_like_internal (conversion *convs > TREE_CONSTANT (new_ctor) = false; > } > /* Build up the array. */ > - elttype = cp_build_qualified_type > - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); > + elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype) > + | TYPE_QUAL_CONST); > array = build_array_of_n_type (elttype, len); > array = finish_compound_literal (array, new_ctor, complain); > /* This is dubious now, should be blessed by P2752. */ > --- gcc/testsuite/g++.dg/cpp/embed-15.C.jj 2024-12-19 15:07:28.564605983 +0100 > +++ gcc/testsuite/g++.dg/cpp/embed-15.C 2024-12-19 15:08:14.194998077 +0100 > @@ -0,0 +1,35 @@ > +// PR c++/118124 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > + > +namespace std { > +template <class T> struct initializer_list { > +private: > + const T *_M_array; > + __SIZE_TYPE__ _M_len; > +}; > +} > +struct A { > + A (std::initializer_list<char>); > +}; > +A a { > +#embed __FILE__ > +}; > +struct B { > + B (std::initializer_list<unsigned char>); > +}; > +B b { > +#embed __FILE__ > +}; > +struct C { > + C (std::initializer_list<int>); > +}; > +C c { > +#embed __FILE__ > +}; > +struct D { > + D (std::initializer_list<float>); > +}; > +D d { > +#embed __FILE__ > +}; > --- gcc/testsuite/g++.dg/cpp/embed-16.C.jj 2024-12-19 15:09:20.929109016 +0100 > +++ gcc/testsuite/g++.dg/cpp/embed-16.C 2024-12-19 15:11:12.811618467 +0100 > @@ -0,0 +1,18 @@ > +// PR c++/118124 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > +// non-ASCII chars here: áéí > + > +namespace std { > +template <class T> struct initializer_list { > +private: > + const T *_M_array; > + __SIZE_TYPE__ _M_len; > +}; > +} > +struct A { > + A (std::initializer_list<signed char>); > +}; > +A a { > +#embed __FILE__ > +}; // { dg-error "narrowing conversion of '\[0-9]*' from 'int' to 'signed char'" } > --- gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C.jj 2024-12-19 14:52:17.389013179 +0100 > +++ gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C 2024-12-19 15:06:28.652404163 +0100 > @@ -0,0 +1,47 @@ > +// PR c++/118124 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > + > +namespace std { > +template <class T> struct initializer_list { > +private: > + const T *_M_array; > + __SIZE_TYPE__ _M_len; > +}; > +} > +struct A { > + A (std::initializer_list<char>); > +}; > +A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; > +struct B { > + B (std::initializer_list<unsigned char>); > +}; > +B b { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; > +struct C { > + C (std::initializer_list<int>); > +}; > +C c { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; > +struct D { > + D (std::initializer_list<float>); > +}; > +D d { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; > --- gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C.jj 2024-12-19 14:52:46.517612306 +0100 > +++ gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C 2024-12-19 15:06:52.513086275 +0100 > @@ -0,0 +1,20 @@ > +// PR c++/118124 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > + > +namespace std { > +template <class T> struct initializer_list { > +private: > + const T *_M_array; > + __SIZE_TYPE__ _M_len; > +}; > +} > +struct A { > + A (std::initializer_list<signed char>); > +}; > +A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 209, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; // { dg-error "narrowing conversion of '209' from 'int' to 'signed char'" } > > Jakub > ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] c++, v2: Fix ICEs with large initializer lists or ones including #embed [PR118124] 2024-12-19 16:52 ` Jason Merrill @ 2024-12-19 18:01 ` Jakub Jelinek 2024-12-20 9:24 ` [PATCH] c++, v3: " Jakub Jelinek 0 siblings, 1 reply; 7+ messages in thread From: Jakub Jelinek @ 2024-12-19 18:01 UTC (permalink / raw) To: Jason Merrill; +Cc: gcc-patches On Thu, Dec 19, 2024 at 11:52:33AM -0500, Jason Merrill wrote: > Please add this paragraph as a comment. Ok. > > + if (!TYPE_UNSIGNED (elt_type) > > + && (complain & tf_warning) > > We shouldn't check tf_warning here. Oops, you're right. I saw the complain & tf_warning early exit at the start of check_narrowing, but that is for C++98 only and I think C++98 code shouldn't get into ck_list handling. > > + && (TYPE_UNSIGNED (TREE_TYPE (val)) > > + || (TYPE_PRECISION (TREE_TYPE (val)) > > + > CHAR_BIT))) > > + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) > > + if (RAW_DATA_SCHAR_ELT (val, i) < 0) > > + { > > Instead, check tf_warning_or_error here, and return error_mark_node if it's > not set. check_narrowing actually tests just complain & tf_error: if not cxx98 nor !CONSTANT_CLASS_P (init) (RAW_DATA_CST is necessarily constant): else if (complain & tf_error) { int savederrorcount = errorcount; permerror_opt (loc, OPT_Wnarrowing, "narrowing conversion of %qE from %qH to %qI", init, ftype, type); if (errorcount == savederrorcount) ok = true; } } return ok; So I went with complain & tf_error check and return error_mark_node if that is 0. So far lightly tested, ok for trunk this way if it passes bootstrap & testing? 2024-12-19 Jakub Jelinek <jakub@redhat.com> PR c++/118124 * call.cc (convert_like_internal): Handle RAW_DATA_CST in ck_list handling. Formatting fixes. * g++.dg/cpp/embed-15.C: New test. * g++.dg/cpp/embed-16.C: New test. * g++.dg/cpp0x/initlist-opt3.C: New test. * g++.dg/cpp0x/initlist-opt4.C: New test. --- gcc/cp/call.cc.jj 2024-12-11 17:27:52.481221310 +0100 +++ gcc/cp/call.cc 2024-12-19 18:50:52.478315892 +0100 @@ -8766,8 +8766,8 @@ convert_like_internal (conversion *convs if (tree init = maybe_init_list_as_array (elttype, expr)) { - elttype = cp_build_qualified_type - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); + elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype) + | TYPE_QUAL_CONST); array = build_array_of_n_type (elttype, len); array = build_vec_init_expr (array, init, complain); array = get_target_expr (array); @@ -8775,13 +8775,83 @@ convert_like_internal (conversion *convs } else if (len) { - tree val; unsigned ix; - + tree val; + unsigned ix; tree new_ctor = build_constructor (init_list_type_node, NULL); /* Convert all the elements. */ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val) { + if (TREE_CODE (val) == RAW_DATA_CST) + { + tree elt_type; + conversion *next; + /* For conversion to initializer_list<unsigned char> or + initializer_list<char> or initializer_list<signed char> + we can optimize and keep RAW_DATA_CST with adjusted + type if we report narrowing errors if needed, for + others this converts each element separately. */ + if (convs->u.list[ix]->kind == ck_std + && (elt_type = convs->u.list[ix]->type) + && (TREE_CODE (elt_type) == INTEGER_TYPE + || is_byte_access_type (elt_type)) + && TYPE_PRECISION (elt_type) == CHAR_BIT + && (next = next_conversion (convs->u.list[ix])) + && next->kind == ck_identity) + { + if (!TYPE_UNSIGNED (elt_type) + && (TYPE_UNSIGNED (TREE_TYPE (val)) + || (TYPE_PRECISION (TREE_TYPE (val)) + > CHAR_BIT))) + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) + if (RAW_DATA_SCHAR_ELT (val, i) >= 0) + continue; + else if (complain & tf_error) + { + location_t loc + = cp_expr_loc_or_input_loc (val); + int savederrorcount = errorcount; + permerror_opt (loc, OPT_Wnarrowing, + "narrowing conversion of %qd " + "from %qH to %qI", + RAW_DATA_UCHAR_ELT (val, i), + TREE_TYPE (val), elt_type); + if (errorcount != savederrorcount) + return error_mark_node; + } + else + return error_mark_node; + tree sub = copy_node (val); + TREE_TYPE (sub) = elt_type; + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), + NULL_TREE, sub); + } + else + { + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) + { + tree elt + = build_int_cst (TREE_TYPE (val), + RAW_DATA_UCHAR_ELT (val, i)); + tree sub + = convert_like (convs->u.list[ix], elt, + fn, argnum, false, false, + /*nested_p=*/true, complain); + if (sub == error_mark_node) + return sub; + if (!check_narrowing (TREE_TYPE (sub), elt, + complain)) + return error_mark_node; + tree nc = new_ctor; + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (nc), + NULL_TREE, sub); + if (!TREE_CONSTANT (sub)) + TREE_CONSTANT (new_ctor) = false; + } + } + len += RAW_DATA_LENGTH (val) - 1; + continue; + } tree sub = convert_like (convs->u.list[ix], val, fn, argnum, false, false, /*nested_p=*/true, complain); @@ -8796,8 +8866,8 @@ convert_like_internal (conversion *convs TREE_CONSTANT (new_ctor) = false; } /* Build up the array. */ - elttype = cp_build_qualified_type - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); + elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype) + | TYPE_QUAL_CONST); array = build_array_of_n_type (elttype, len); array = finish_compound_literal (array, new_ctor, complain); /* This is dubious now, should be blessed by P2752. */ --- gcc/testsuite/g++.dg/cpp/embed-15.C.jj 2024-12-19 15:07:28.564605983 +0100 +++ gcc/testsuite/g++.dg/cpp/embed-15.C 2024-12-19 15:08:14.194998077 +0100 @@ -0,0 +1,35 @@ +// PR c++/118124 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +namespace std { +template <class T> struct initializer_list { +private: + const T *_M_array; + __SIZE_TYPE__ _M_len; +}; +} +struct A { + A (std::initializer_list<char>); +}; +A a { +#embed __FILE__ +}; +struct B { + B (std::initializer_list<unsigned char>); +}; +B b { +#embed __FILE__ +}; +struct C { + C (std::initializer_list<int>); +}; +C c { +#embed __FILE__ +}; +struct D { + D (std::initializer_list<float>); +}; +D d { +#embed __FILE__ +}; --- gcc/testsuite/g++.dg/cpp/embed-16.C.jj 2024-12-19 15:09:20.929109016 +0100 +++ gcc/testsuite/g++.dg/cpp/embed-16.C 2024-12-19 15:11:12.811618467 +0100 @@ -0,0 +1,18 @@ +// PR c++/118124 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } +// non-ASCII chars here: áéí + +namespace std { +template <class T> struct initializer_list { +private: + const T *_M_array; + __SIZE_TYPE__ _M_len; +}; +} +struct A { + A (std::initializer_list<signed char>); +}; +A a { +#embed __FILE__ +}; // { dg-error "narrowing conversion of '\[0-9]*' from 'int' to 'signed char'" } --- gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C.jj 2024-12-19 14:52:17.389013179 +0100 +++ gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C 2024-12-19 15:06:28.652404163 +0100 @@ -0,0 +1,47 @@ +// PR c++/118124 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +namespace std { +template <class T> struct initializer_list { +private: + const T *_M_array; + __SIZE_TYPE__ _M_len; +}; +} +struct A { + A (std::initializer_list<char>); +}; +A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; +struct B { + B (std::initializer_list<unsigned char>); +}; +B b { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; +struct C { + C (std::initializer_list<int>); +}; +C c { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; +struct D { + D (std::initializer_list<float>); +}; +D d { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; --- gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C.jj 2024-12-19 14:52:46.517612306 +0100 +++ gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C 2024-12-19 15:06:52.513086275 +0100 @@ -0,0 +1,20 @@ +// PR c++/118124 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +namespace std { +template <class T> struct initializer_list { +private: + const T *_M_array; + __SIZE_TYPE__ _M_len; +}; +} +struct A { + A (std::initializer_list<signed char>); +}; +A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 209, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; // { dg-error "narrowing conversion of '209' from 'int' to 'signed char'" } Jakub ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] c++, v3: Fix ICEs with large initializer lists or ones including #embed [PR118124] 2024-12-19 18:01 ` [PATCH] c++, v2: " Jakub Jelinek @ 2024-12-20 9:24 ` Jakub Jelinek 2025-01-10 2:30 ` Jason Merrill 0 siblings, 1 reply; 7+ messages in thread From: Jakub Jelinek @ 2024-12-20 9:24 UTC (permalink / raw) To: Jason Merrill; +Cc: gcc-patches On Thu, Dec 19, 2024 at 07:01:39PM +0100, Jakub Jelinek wrote: > So far lightly tested, ok for trunk this way if it passes bootstrap & testing? Bootstrap/regtest found an issue, warning about if () for () if () else if () else so I've added {}s around it (no other changes from the previous patch). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-12-20 Jakub Jelinek <jakub@redhat.com> PR c++/118124 * call.cc (convert_like_internal): Handle RAW_DATA_CST in ck_list handling. Formatting fixes. * g++.dg/cpp/embed-15.C: New test. * g++.dg/cpp/embed-16.C: New test. * g++.dg/cpp0x/initlist-opt3.C: New test. * g++.dg/cpp0x/initlist-opt4.C: New test. --- gcc/cp/call.cc.jj 2024-12-11 17:27:52.481221310 +0100 +++ gcc/cp/call.cc 2024-12-19 18:50:52.478315892 +0100 @@ -8766,8 +8766,8 @@ convert_like_internal (conversion *convs if (tree init = maybe_init_list_as_array (elttype, expr)) { - elttype = cp_build_qualified_type - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); + elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype) + | TYPE_QUAL_CONST); array = build_array_of_n_type (elttype, len); array = build_vec_init_expr (array, init, complain); array = get_target_expr (array); @@ -8775,13 +8775,85 @@ convert_like_internal (conversion *convs } else if (len) { - tree val; unsigned ix; - + tree val; + unsigned ix; tree new_ctor = build_constructor (init_list_type_node, NULL); /* Convert all the elements. */ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val) { + if (TREE_CODE (val) == RAW_DATA_CST) + { + tree elt_type; + conversion *next; + /* For conversion to initializer_list<unsigned char> or + initializer_list<char> or initializer_list<signed char> + we can optimize and keep RAW_DATA_CST with adjusted + type if we report narrowing errors if needed, for + others this converts each element separately. */ + if (convs->u.list[ix]->kind == ck_std + && (elt_type = convs->u.list[ix]->type) + && (TREE_CODE (elt_type) == INTEGER_TYPE + || is_byte_access_type (elt_type)) + && TYPE_PRECISION (elt_type) == CHAR_BIT + && (next = next_conversion (convs->u.list[ix])) + && next->kind == ck_identity) + { + if (!TYPE_UNSIGNED (elt_type) + && (TYPE_UNSIGNED (TREE_TYPE (val)) + || (TYPE_PRECISION (TREE_TYPE (val)) + > CHAR_BIT))) + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) + { + if (RAW_DATA_SCHAR_ELT (val, i) >= 0) + continue; + else if (complain & tf_error) + { + location_t loc + = cp_expr_loc_or_input_loc (val); + int savederrorcount = errorcount; + permerror_opt (loc, OPT_Wnarrowing, + "narrowing conversion of " + "%qd from %qH to %qI", + RAW_DATA_UCHAR_ELT (val, i), + TREE_TYPE (val), elt_type); + if (errorcount != savederrorcount) + return error_mark_node; + } + else + return error_mark_node; + } + tree sub = copy_node (val); + TREE_TYPE (sub) = elt_type; + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), + NULL_TREE, sub); + } + else + { + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) + { + tree elt + = build_int_cst (TREE_TYPE (val), + RAW_DATA_UCHAR_ELT (val, i)); + tree sub + = convert_like (convs->u.list[ix], elt, + fn, argnum, false, false, + /*nested_p=*/true, complain); + if (sub == error_mark_node) + return sub; + if (!check_narrowing (TREE_TYPE (sub), elt, + complain)) + return error_mark_node; + tree nc = new_ctor; + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (nc), + NULL_TREE, sub); + if (!TREE_CONSTANT (sub)) + TREE_CONSTANT (new_ctor) = false; + } + } + len += RAW_DATA_LENGTH (val) - 1; + continue; + } tree sub = convert_like (convs->u.list[ix], val, fn, argnum, false, false, /*nested_p=*/true, complain); @@ -8796,8 +8868,8 @@ convert_like_internal (conversion *convs TREE_CONSTANT (new_ctor) = false; } /* Build up the array. */ - elttype = cp_build_qualified_type - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); + elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype) + | TYPE_QUAL_CONST); array = build_array_of_n_type (elttype, len); array = finish_compound_literal (array, new_ctor, complain); /* This is dubious now, should be blessed by P2752. */ --- gcc/testsuite/g++.dg/cpp/embed-15.C.jj 2024-12-19 15:07:28.564605983 +0100 +++ gcc/testsuite/g++.dg/cpp/embed-15.C 2024-12-19 15:08:14.194998077 +0100 @@ -0,0 +1,35 @@ +// PR c++/118124 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +namespace std { +template <class T> struct initializer_list { +private: + const T *_M_array; + __SIZE_TYPE__ _M_len; +}; +} +struct A { + A (std::initializer_list<char>); +}; +A a { +#embed __FILE__ +}; +struct B { + B (std::initializer_list<unsigned char>); +}; +B b { +#embed __FILE__ +}; +struct C { + C (std::initializer_list<int>); +}; +C c { +#embed __FILE__ +}; +struct D { + D (std::initializer_list<float>); +}; +D d { +#embed __FILE__ +}; --- gcc/testsuite/g++.dg/cpp/embed-16.C.jj 2024-12-19 15:09:20.929109016 +0100 +++ gcc/testsuite/g++.dg/cpp/embed-16.C 2024-12-19 15:11:12.811618467 +0100 @@ -0,0 +1,18 @@ +// PR c++/118124 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } +// non-ASCII chars here: áéí + +namespace std { +template <class T> struct initializer_list { +private: + const T *_M_array; + __SIZE_TYPE__ _M_len; +}; +} +struct A { + A (std::initializer_list<signed char>); +}; +A a { +#embed __FILE__ +}; // { dg-error "narrowing conversion of '\[0-9]*' from 'int' to 'signed char'" } --- gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C.jj 2024-12-19 14:52:17.389013179 +0100 +++ gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C 2024-12-19 15:06:28.652404163 +0100 @@ -0,0 +1,47 @@ +// PR c++/118124 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +namespace std { +template <class T> struct initializer_list { +private: + const T *_M_array; + __SIZE_TYPE__ _M_len; +}; +} +struct A { + A (std::initializer_list<char>); +}; +A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; +struct B { + B (std::initializer_list<unsigned char>); +}; +B b { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; +struct C { + C (std::initializer_list<int>); +}; +C c { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; +struct D { + D (std::initializer_list<float>); +}; +D d { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; --- gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C.jj 2024-12-19 14:52:46.517612306 +0100 +++ gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C 2024-12-19 15:06:52.513086275 +0100 @@ -0,0 +1,20 @@ +// PR c++/118124 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +namespace std { +template <class T> struct initializer_list { +private: + const T *_M_array; + __SIZE_TYPE__ _M_len; +}; +} +struct A { + A (std::initializer_list<signed char>); +}; +A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 209, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; // { dg-error "narrowing conversion of '209' from 'int' to 'signed char'" } Jakub ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] c++, v3: Fix ICEs with large initializer lists or ones including #embed [PR118124] 2024-12-20 9:24 ` [PATCH] c++, v3: " Jakub Jelinek @ 2025-01-10 2:30 ` Jason Merrill 2025-01-10 9:21 ` Jakub Jelinek 0 siblings, 1 reply; 7+ messages in thread From: Jason Merrill @ 2025-01-10 2:30 UTC (permalink / raw) To: Jakub Jelinek; +Cc: gcc-patches On 12/20/24 4:24 AM, Jakub Jelinek wrote: > On Thu, Dec 19, 2024 at 07:01:39PM +0100, Jakub Jelinek wrote: >> So far lightly tested, ok for trunk this way if it passes bootstrap & testing? > > Bootstrap/regtest found an issue, warning about > if () > for () > if () > else if () > else > so I've added {}s around it (no other changes from the previous patch). > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2024-12-20 Jakub Jelinek <jakub@redhat.com> > > PR c++/118124 > * call.cc (convert_like_internal): Handle RAW_DATA_CST in > ck_list handling. Formatting fixes. > > * g++.dg/cpp/embed-15.C: New test. > * g++.dg/cpp/embed-16.C: New test. > * g++.dg/cpp0x/initlist-opt3.C: New test. > * g++.dg/cpp0x/initlist-opt4.C: New test. > > --- gcc/cp/call.cc.jj 2024-12-11 17:27:52.481221310 +0100 > +++ gcc/cp/call.cc 2024-12-19 18:50:52.478315892 +0100 > @@ -8766,8 +8766,8 @@ convert_like_internal (conversion *convs > > if (tree init = maybe_init_list_as_array (elttype, expr)) > { > - elttype = cp_build_qualified_type > - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); > + elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype) > + | TYPE_QUAL_CONST); Emacs won't preserve this formatting, it will move the | left to line up with the (. > array = build_array_of_n_type (elttype, len); > array = build_vec_init_expr (array, init, complain); > array = get_target_expr (array); > @@ -8775,13 +8775,85 @@ convert_like_internal (conversion *convs > } > else if (len) > { > - tree val; unsigned ix; > - > + tree val; > + unsigned ix; > tree new_ctor = build_constructor (init_list_type_node, NULL); > > /* Convert all the elements. */ > FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val) > { > + if (TREE_CODE (val) == RAW_DATA_CST) > + { > + tree elt_type; > + conversion *next; > + /* For conversion to initializer_list<unsigned char> or > + initializer_list<char> or initializer_list<signed char> > + we can optimize and keep RAW_DATA_CST with adjusted > + type if we report narrowing errors if needed, for > + others this converts each element separately. */ > + if (convs->u.list[ix]->kind == ck_std > + && (elt_type = convs->u.list[ix]->type) > + && (TREE_CODE (elt_type) == INTEGER_TYPE > + || is_byte_access_type (elt_type)) > + && TYPE_PRECISION (elt_type) == CHAR_BIT > + && (next = next_conversion (convs->u.list[ix])) > + && next->kind == ck_identity) > + { > + if (!TYPE_UNSIGNED (elt_type) > + && (TYPE_UNSIGNED (TREE_TYPE (val)) > + || (TYPE_PRECISION (TREE_TYPE (val)) > + > CHAR_BIT))) Is it possible to have a RAW_DATA_CST with elements larger than char? > + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) > + { > + if (RAW_DATA_SCHAR_ELT (val, i) >= 0) > + continue; > + else if (complain & tf_error) > + { > + location_t loc > + = cp_expr_loc_or_input_loc (val); > + int savederrorcount = errorcount; > + permerror_opt (loc, OPT_Wnarrowing, > + "narrowing conversion of " > + "%qd from %qH to %qI", > + RAW_DATA_UCHAR_ELT (val, i), > + TREE_TYPE (val), elt_type); > + if (errorcount != savederrorcount) > + return error_mark_node; > + } > + else > + return error_mark_node; > + } > + tree sub = copy_node (val); > + TREE_TYPE (sub) = elt_type; > + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), > + NULL_TREE, sub); > + } > + else > + { > + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) > + { > + tree elt > + = build_int_cst (TREE_TYPE (val), > + RAW_DATA_UCHAR_ELT (val, i)); > + tree sub > + = convert_like (convs->u.list[ix], elt, > + fn, argnum, false, false, > + /*nested_p=*/true, complain); > + if (sub == error_mark_node) > + return sub; > + if (!check_narrowing (TREE_TYPE (sub), elt, > + complain)) > + return error_mark_node; > + tree nc = new_ctor; > + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (nc), > + NULL_TREE, sub); > + if (!TREE_CONSTANT (sub)) > + TREE_CONSTANT (new_ctor) = false; > + } > + } > + len += RAW_DATA_LENGTH (val) - 1; > + continue; > + } > tree sub = convert_like (convs->u.list[ix], val, fn, > argnum, false, false, > /*nested_p=*/true, complain); > @@ -8796,8 +8868,8 @@ convert_like_internal (conversion *convs > TREE_CONSTANT (new_ctor) = false; > } > /* Build up the array. */ > - elttype = cp_build_qualified_type > - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); > + elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype) > + | TYPE_QUAL_CONST); Questionable reformatting again. The patch is OK without the unrelated reformatting, but I'd like a clarification about the precision question, perhaps in a comment. Jason > array = build_array_of_n_type (elttype, len); > array = finish_compound_literal (array, new_ctor, complain); > /* This is dubious now, should be blessed by P2752. */ > --- gcc/testsuite/g++.dg/cpp/embed-15.C.jj 2024-12-19 15:07:28.564605983 +0100 > +++ gcc/testsuite/g++.dg/cpp/embed-15.C 2024-12-19 15:08:14.194998077 +0100 > @@ -0,0 +1,35 @@ > +// PR c++/118124 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > + > +namespace std { > +template <class T> struct initializer_list { > +private: > + const T *_M_array; > + __SIZE_TYPE__ _M_len; > +}; > +} > +struct A { > + A (std::initializer_list<char>); > +}; > +A a { > +#embed __FILE__ > +}; > +struct B { > + B (std::initializer_list<unsigned char>); > +}; > +B b { > +#embed __FILE__ > +}; > +struct C { > + C (std::initializer_list<int>); > +}; > +C c { > +#embed __FILE__ > +}; > +struct D { > + D (std::initializer_list<float>); > +}; > +D d { > +#embed __FILE__ > +}; > --- gcc/testsuite/g++.dg/cpp/embed-16.C.jj 2024-12-19 15:09:20.929109016 +0100 > +++ gcc/testsuite/g++.dg/cpp/embed-16.C 2024-12-19 15:11:12.811618467 +0100 > @@ -0,0 +1,18 @@ > +// PR c++/118124 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > +// non-ASCII chars here: áéí > + > +namespace std { > +template <class T> struct initializer_list { > +private: > + const T *_M_array; > + __SIZE_TYPE__ _M_len; > +}; > +} > +struct A { > + A (std::initializer_list<signed char>); > +}; > +A a { > +#embed __FILE__ > +}; // { dg-error "narrowing conversion of '\[0-9]*' from 'int' to 'signed char'" } > --- gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C.jj 2024-12-19 14:52:17.389013179 +0100 > +++ gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C 2024-12-19 15:06:28.652404163 +0100 > @@ -0,0 +1,47 @@ > +// PR c++/118124 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > + > +namespace std { > +template <class T> struct initializer_list { > +private: > + const T *_M_array; > + __SIZE_TYPE__ _M_len; > +}; > +} > +struct A { > + A (std::initializer_list<char>); > +}; > +A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; > +struct B { > + B (std::initializer_list<unsigned char>); > +}; > +B b { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; > +struct C { > + C (std::initializer_list<int>); > +}; > +C c { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; > +struct D { > + D (std::initializer_list<float>); > +}; > +D d { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; > --- gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C.jj 2024-12-19 14:52:46.517612306 +0100 > +++ gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C 2024-12-19 15:06:52.513086275 +0100 > @@ -0,0 +1,20 @@ > +// PR c++/118124 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > + > +namespace std { > +template <class T> struct initializer_list { > +private: > + const T *_M_array; > + __SIZE_TYPE__ _M_len; > +}; > +} > +struct A { > + A (std::initializer_list<signed char>); > +}; > +A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 209, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; // { dg-error "narrowing conversion of '209' from 'int' to 'signed char'" } > > > Jakub > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] c++, v3: Fix ICEs with large initializer lists or ones including #embed [PR118124] 2025-01-10 2:30 ` Jason Merrill @ 2025-01-10 9:21 ` Jakub Jelinek 2025-01-15 0:52 ` Jason Merrill 0 siblings, 1 reply; 7+ messages in thread From: Jakub Jelinek @ 2025-01-10 9:21 UTC (permalink / raw) To: Jason Merrill; +Cc: gcc-patches On Thu, Jan 09, 2025 at 09:30:04PM -0500, Jason Merrill wrote: > > --- gcc/cp/call.cc.jj 2024-12-11 17:27:52.481221310 +0100 > > +++ gcc/cp/call.cc 2024-12-19 18:50:52.478315892 +0100 > > @@ -8766,8 +8766,8 @@ convert_like_internal (conversion *convs > > if (tree init = maybe_init_list_as_array (elttype, expr)) > > { > > - elttype = cp_build_qualified_type > > - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); > > + elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype) > > + | TYPE_QUAL_CONST); > > Emacs won't preserve this formatting, it will move the | left to line up > with the (. So elttype = cp_build_qualified_type (elttype, (cp_type_quals (elttype) | TYPE_QUAL_CONST)); then or elttype = cp_build_qualified_type (elttype, (cp_type_quals (elttype) | TYPE_QUAL_CONST)); ? The function-name on different line from the ( and first parameter is just weird and last resort when nothing else works. > > + if (TREE_CODE (val) == RAW_DATA_CST) > > + { > > + tree elt_type; > > + conversion *next; > > + /* For conversion to initializer_list<unsigned char> or > > + initializer_list<char> or initializer_list<signed char> > > + we can optimize and keep RAW_DATA_CST with adjusted > > + type if we report narrowing errors if needed, for > > + others this converts each element separately. */ > > + if (convs->u.list[ix]->kind == ck_std > > + && (elt_type = convs->u.list[ix]->type) > > + && (TREE_CODE (elt_type) == INTEGER_TYPE > > + || is_byte_access_type (elt_type)) > > + && TYPE_PRECISION (elt_type) == CHAR_BIT > > + && (next = next_conversion (convs->u.list[ix])) > > + && next->kind == ck_identity) > > + { > > + if (!TYPE_UNSIGNED (elt_type) > > + && (TYPE_UNSIGNED (TREE_TYPE (val)) > > + || (TYPE_PRECISION (TREE_TYPE (val)) > > + > CHAR_BIT))) > > Is it possible to have a RAW_DATA_CST with elements larger than char? Initially, RAW_DATA_CST has int type, i.e. the type each element would have if it was just 1, 2, 3, 4, 5, 6, 7, 8, 9, ..., 115, 116, 117, 118 and then the reshaping turns it either into char/signed char/unsigned char or perhaps std::byte (i.e. something CHAR_BIT), or splits it appart. As I saw some bool variable somewhere in the code whether the CONSTRUCTOR has been reshaped or not (unfortunately don't remember where and can't find it now), I've tried to be safe for both cases, i.e. handle both the int case where we know the values are 0 .. CHAR_BIT-1 with some extra bits on top, so even when TREE_TYPE (val) is signed, the values need to be taken as unsigned, and then the reshaped ones where !TYPE_UNSIGNED implies elts with most significant bit set are negative. If TREE_TYPE (val) is signed char (or char with -fsigned-char), then -Wnarrowing is supposed to have been already diagnosed when it was converted from int to signed char (either in digest_init_r or in this spot before). On the testcases from this patch, TREE_TYPE (val) is still integer_type_node. Even that could have precision CHAR_BIT, e.g. on avr with -mint8, I think we just shouldn't create RAW_DATA_CST at all in that case if any of the bytes is above SCHAR_MAX, because then in 1, 2, 3, 128, 4, 5 the 128 has long or long long type rather than int, while the rest have int. Maybe even preprocessor shouldn't create CPP_EMBED then, but dunno if libcpp knows the precision of int on the target. I'll deal with avr -mint8 later on during stage4 (guess it affects C as well). Here is an updated patch with changed formatting of the cp_build_qualified_type calls and comment added. If you really don't want the formatting changes, I can surely take that out, and if you think being there extra careful about TREE_TYPE (val) isn't needed either because it must be always integer_type_node and that libcpp shouldn't create CPP_EMBED for avr -mint8 with 128+ values, that conditional could be just if (!TYPE_UNSIGNED (elt_type)) alone as well. 2025-01-10 Jakub Jelinek <jakub@redhat.com> PR c++/118124 * call.cc (convert_like_internal): Handle RAW_DATA_CST in ck_list handling. Formatting fixes. * g++.dg/cpp/embed-15.C: New test. * g++.dg/cpp/embed-16.C: New test. * g++.dg/cpp0x/initlist-opt3.C: New test. * g++.dg/cpp0x/initlist-opt4.C: New test. --- gcc/cp/call.cc.jj 2024-12-11 17:27:52.481221310 +0100 +++ gcc/cp/call.cc 2025-01-10 10:13:25.268639098 +0100 @@ -8806,8 +8806,9 @@ convert_like_internal (conversion *convs if (tree init = maybe_init_list_as_array (elttype, expr)) { - elttype = cp_build_qualified_type - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); + elttype + = cp_build_qualified_type (elttype, (cp_type_quals (elttype) + | TYPE_QUAL_CONST)); array = build_array_of_n_type (elttype, len); array = build_vec_init_expr (array, init, complain); array = get_target_expr (array); @@ -8815,13 +8816,94 @@ convert_like_internal (conversion *convs } else if (len) { - tree val; unsigned ix; - + tree val; + unsigned ix; tree new_ctor = build_constructor (init_list_type_node, NULL); /* Convert all the elements. */ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val) { + if (TREE_CODE (val) == RAW_DATA_CST) + { + tree elt_type; + conversion *next; + /* For conversion to initializer_list<unsigned char> or + initializer_list<char> or initializer_list<signed char> + we can optimize and keep RAW_DATA_CST with adjusted + type if we report narrowing errors if needed, for + others this converts each element separately. */ + if (convs->u.list[ix]->kind == ck_std + && (elt_type = convs->u.list[ix]->type) + && (TREE_CODE (elt_type) == INTEGER_TYPE + || is_byte_access_type (elt_type)) + && TYPE_PRECISION (elt_type) == CHAR_BIT + && (next = next_conversion (convs->u.list[ix])) + && next->kind == ck_identity) + { + if (!TYPE_UNSIGNED (elt_type) + /* For RAW_DATA_CST, TREE_TYPE (val) can be + either integer_type_node (when it has been + created by the lexer from CPP_EMBED) or + after digestion/conversion some integral + type with CHAR_BIT precision. For int with + precision higher than CHAR_BIT or unsigned char + diagnose narrowing conversions from + that int/unsigned char to signed char if any + byte has most significant bit set. */ + && (TYPE_UNSIGNED (TREE_TYPE (val)) + || (TYPE_PRECISION (TREE_TYPE (val)) + > CHAR_BIT))) + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) + { + if (RAW_DATA_SCHAR_ELT (val, i) >= 0) + continue; + else if (complain & tf_error) + { + location_t loc + = cp_expr_loc_or_input_loc (val); + int savederrorcount = errorcount; + permerror_opt (loc, OPT_Wnarrowing, + "narrowing conversion of " + "%qd from %qH to %qI", + RAW_DATA_UCHAR_ELT (val, i), + TREE_TYPE (val), elt_type); + if (errorcount != savederrorcount) + return error_mark_node; + } + else + return error_mark_node; + } + tree sub = copy_node (val); + TREE_TYPE (sub) = elt_type; + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), + NULL_TREE, sub); + } + else + { + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) + { + tree elt + = build_int_cst (TREE_TYPE (val), + RAW_DATA_UCHAR_ELT (val, i)); + tree sub + = convert_like (convs->u.list[ix], elt, + fn, argnum, false, false, + /*nested_p=*/true, complain); + if (sub == error_mark_node) + return sub; + if (!check_narrowing (TREE_TYPE (sub), elt, + complain)) + return error_mark_node; + tree nc = new_ctor; + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (nc), + NULL_TREE, sub); + if (!TREE_CONSTANT (sub)) + TREE_CONSTANT (new_ctor) = false; + } + } + len += RAW_DATA_LENGTH (val) - 1; + continue; + } tree sub = convert_like (convs->u.list[ix], val, fn, argnum, false, false, /*nested_p=*/true, complain); @@ -8836,8 +8918,9 @@ convert_like_internal (conversion *convs TREE_CONSTANT (new_ctor) = false; } /* Build up the array. */ - elttype = cp_build_qualified_type - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); + elttype + = cp_build_qualified_type (elttype, (cp_type_quals (elttype) + | TYPE_QUAL_CONST)); array = build_array_of_n_type (elttype, len); array = finish_compound_literal (array, new_ctor, complain); /* This is dubious now, should be blessed by P2752. */ --- gcc/testsuite/g++.dg/cpp/embed-15.C.jj 2024-12-19 15:07:28.564605983 +0100 +++ gcc/testsuite/g++.dg/cpp/embed-15.C 2024-12-19 15:08:14.194998077 +0100 @@ -0,0 +1,35 @@ +// PR c++/118124 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +namespace std { +template <class T> struct initializer_list { +private: + const T *_M_array; + __SIZE_TYPE__ _M_len; +}; +} +struct A { + A (std::initializer_list<char>); +}; +A a { +#embed __FILE__ +}; +struct B { + B (std::initializer_list<unsigned char>); +}; +B b { +#embed __FILE__ +}; +struct C { + C (std::initializer_list<int>); +}; +C c { +#embed __FILE__ +}; +struct D { + D (std::initializer_list<float>); +}; +D d { +#embed __FILE__ +}; --- gcc/testsuite/g++.dg/cpp/embed-16.C.jj 2024-12-19 15:09:20.929109016 +0100 +++ gcc/testsuite/g++.dg/cpp/embed-16.C 2024-12-19 15:11:12.811618467 +0100 @@ -0,0 +1,18 @@ +// PR c++/118124 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } +// non-ASCII chars here: áéí + +namespace std { +template <class T> struct initializer_list { +private: + const T *_M_array; + __SIZE_TYPE__ _M_len; +}; +} +struct A { + A (std::initializer_list<signed char>); +}; +A a { +#embed __FILE__ +}; // { dg-error "narrowing conversion of '\[0-9]*' from 'int' to 'signed char'" } --- gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C.jj 2024-12-19 14:52:17.389013179 +0100 +++ gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C 2024-12-19 15:06:28.652404163 +0100 @@ -0,0 +1,47 @@ +// PR c++/118124 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +namespace std { +template <class T> struct initializer_list { +private: + const T *_M_array; + __SIZE_TYPE__ _M_len; +}; +} +struct A { + A (std::initializer_list<char>); +}; +A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; +struct B { + B (std::initializer_list<unsigned char>); +}; +B b { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; +struct C { + C (std::initializer_list<int>); +}; +C c { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; +struct D { + D (std::initializer_list<float>); +}; +D d { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; --- gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C.jj 2024-12-19 14:52:46.517612306 +0100 +++ gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C 2024-12-19 15:06:52.513086275 +0100 @@ -0,0 +1,20 @@ +// PR c++/118124 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +namespace std { +template <class T> struct initializer_list { +private: + const T *_M_array; + __SIZE_TYPE__ _M_len; +}; +} +struct A { + A (std::initializer_list<signed char>); +}; +A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 209, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; // { dg-error "narrowing conversion of '209' from 'int' to 'signed char'" } Jakub ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] c++, v3: Fix ICEs with large initializer lists or ones including #embed [PR118124] 2025-01-10 9:21 ` Jakub Jelinek @ 2025-01-15 0:52 ` Jason Merrill 0 siblings, 0 replies; 7+ messages in thread From: Jason Merrill @ 2025-01-15 0:52 UTC (permalink / raw) To: Jakub Jelinek; +Cc: gcc-patches On 1/10/25 4:21 AM, Jakub Jelinek wrote: > On Thu, Jan 09, 2025 at 09:30:04PM -0500, Jason Merrill wrote: >>> --- gcc/cp/call.cc.jj 2024-12-11 17:27:52.481221310 +0100 >>> +++ gcc/cp/call.cc 2024-12-19 18:50:52.478315892 +0100 >>> @@ -8766,8 +8766,8 @@ convert_like_internal (conversion *convs >>> if (tree init = maybe_init_list_as_array (elttype, expr)) >>> { >>> - elttype = cp_build_qualified_type >>> - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); >>> + elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype) >>> + | TYPE_QUAL_CONST); >> >> Emacs won't preserve this formatting, it will move the | left to line up >> with the (. > > So > elttype = cp_build_qualified_type (elttype, > (cp_type_quals (elttype) > | TYPE_QUAL_CONST)); > then or > elttype > = cp_build_qualified_type (elttype, (cp_type_quals (elttype) > | TYPE_QUAL_CONST)); > ? The function-name on different line from the ( and first parameter is > just weird and last resort when nothing else works. Either is fine. >>> + if (TREE_CODE (val) == RAW_DATA_CST) >>> + { >>> + tree elt_type; >>> + conversion *next; >>> + /* For conversion to initializer_list<unsigned char> or >>> + initializer_list<char> or initializer_list<signed char> >>> + we can optimize and keep RAW_DATA_CST with adjusted >>> + type if we report narrowing errors if needed, for >>> + others this converts each element separately. */ >>> + if (convs->u.list[ix]->kind == ck_std >>> + && (elt_type = convs->u.list[ix]->type) >>> + && (TREE_CODE (elt_type) == INTEGER_TYPE >>> + || is_byte_access_type (elt_type)) >>> + && TYPE_PRECISION (elt_type) == CHAR_BIT >>> + && (next = next_conversion (convs->u.list[ix])) >>> + && next->kind == ck_identity) >>> + { >>> + if (!TYPE_UNSIGNED (elt_type) >>> + && (TYPE_UNSIGNED (TREE_TYPE (val)) >>> + || (TYPE_PRECISION (TREE_TYPE (val)) >>> + > CHAR_BIT))) >> >> Is it possible to have a RAW_DATA_CST with elements larger than char? > > Initially, RAW_DATA_CST has int type, i.e. the type > each element would have if it was just > 1, 2, 3, 4, 5, 6, 7, 8, 9, ..., 115, 116, 117, 118 > and then the reshaping turns it either into char/signed char/unsigned char > or perhaps std::byte (i.e. something CHAR_BIT), or splits it appart. > > As I saw some bool variable somewhere in the code whether the CONSTRUCTOR > has been reshaped or not (unfortunately don't remember where and can't find > it now), I've tried to be safe for both cases, i.e. handle both the int > case where we know the values are 0 .. CHAR_BIT-1 with some extra bits on > top, so even when TREE_TYPE (val) is signed, the values need to be taken as > unsigned, and then the reshaped ones where !TYPE_UNSIGNED implies elts with > most significant bit set are negative. > If TREE_TYPE (val) is signed char (or char with -fsigned-char), then > -Wnarrowing is supposed to have been already diagnosed when it was converted > from int to signed char (either in digest_init_r or in this spot before). > > On the testcases from this patch, TREE_TYPE (val) is still > integer_type_node. I think what I was missing is that the original values are always unsigned, so you aren't every going to have (int)-128? Then the patch is OK, thanks. > Even that could have precision CHAR_BIT, e.g. on avr > with -mint8, I think we just shouldn't create RAW_DATA_CST at all in that > case if any of the bytes is above SCHAR_MAX, because then in > 1, 2, 3, 128, 4, 5 > the 128 has long or long long type rather than int, while the rest have int. > Maybe even preprocessor shouldn't create CPP_EMBED then, but dunno if libcpp > knows the precision of int on the target. I'll deal with avr -mint8 later on > during stage4 (guess it affects C as well). > > Here is an updated patch with changed formatting of the > cp_build_qualified_type calls and comment added. > If you really don't want the formatting changes, I can surely take that out, > and if you think being there extra careful about TREE_TYPE (val) isn't > needed either because it must be always integer_type_node and that libcpp > shouldn't create CPP_EMBED for avr -mint8 with 128+ values, that conditional > could be just if (!TYPE_UNSIGNED (elt_type)) alone as well. > > 2025-01-10 Jakub Jelinek <jakub@redhat.com> > > PR c++/118124 > * call.cc (convert_like_internal): Handle RAW_DATA_CST in > ck_list handling. Formatting fixes. > > * g++.dg/cpp/embed-15.C: New test. > * g++.dg/cpp/embed-16.C: New test. > * g++.dg/cpp0x/initlist-opt3.C: New test. > * g++.dg/cpp0x/initlist-opt4.C: New test. > > --- gcc/cp/call.cc.jj 2024-12-11 17:27:52.481221310 +0100 > +++ gcc/cp/call.cc 2025-01-10 10:13:25.268639098 +0100 > @@ -8806,8 +8806,9 @@ convert_like_internal (conversion *convs > > if (tree init = maybe_init_list_as_array (elttype, expr)) > { > - elttype = cp_build_qualified_type > - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); > + elttype > + = cp_build_qualified_type (elttype, (cp_type_quals (elttype) > + | TYPE_QUAL_CONST)); > array = build_array_of_n_type (elttype, len); > array = build_vec_init_expr (array, init, complain); > array = get_target_expr (array); > @@ -8815,13 +8816,94 @@ convert_like_internal (conversion *convs > } > else if (len) > { > - tree val; unsigned ix; > - > + tree val; > + unsigned ix; > tree new_ctor = build_constructor (init_list_type_node, NULL); > > /* Convert all the elements. */ > FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val) > { > + if (TREE_CODE (val) == RAW_DATA_CST) > + { > + tree elt_type; > + conversion *next; > + /* For conversion to initializer_list<unsigned char> or > + initializer_list<char> or initializer_list<signed char> > + we can optimize and keep RAW_DATA_CST with adjusted > + type if we report narrowing errors if needed, for > + others this converts each element separately. */ > + if (convs->u.list[ix]->kind == ck_std > + && (elt_type = convs->u.list[ix]->type) > + && (TREE_CODE (elt_type) == INTEGER_TYPE > + || is_byte_access_type (elt_type)) > + && TYPE_PRECISION (elt_type) == CHAR_BIT > + && (next = next_conversion (convs->u.list[ix])) > + && next->kind == ck_identity) > + { > + if (!TYPE_UNSIGNED (elt_type) > + /* For RAW_DATA_CST, TREE_TYPE (val) can be > + either integer_type_node (when it has been > + created by the lexer from CPP_EMBED) or > + after digestion/conversion some integral > + type with CHAR_BIT precision. For int with > + precision higher than CHAR_BIT or unsigned char > + diagnose narrowing conversions from > + that int/unsigned char to signed char if any > + byte has most significant bit set. */ > + && (TYPE_UNSIGNED (TREE_TYPE (val)) > + || (TYPE_PRECISION (TREE_TYPE (val)) > + > CHAR_BIT))) > + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) > + { > + if (RAW_DATA_SCHAR_ELT (val, i) >= 0) > + continue; > + else if (complain & tf_error) > + { > + location_t loc > + = cp_expr_loc_or_input_loc (val); > + int savederrorcount = errorcount; > + permerror_opt (loc, OPT_Wnarrowing, > + "narrowing conversion of " > + "%qd from %qH to %qI", > + RAW_DATA_UCHAR_ELT (val, i), > + TREE_TYPE (val), elt_type); > + if (errorcount != savederrorcount) > + return error_mark_node; > + } > + else > + return error_mark_node; > + } > + tree sub = copy_node (val); > + TREE_TYPE (sub) = elt_type; > + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), > + NULL_TREE, sub); > + } > + else > + { > + for (int i = 0; i < RAW_DATA_LENGTH (val); ++i) > + { > + tree elt > + = build_int_cst (TREE_TYPE (val), > + RAW_DATA_UCHAR_ELT (val, i)); > + tree sub > + = convert_like (convs->u.list[ix], elt, > + fn, argnum, false, false, > + /*nested_p=*/true, complain); > + if (sub == error_mark_node) > + return sub; > + if (!check_narrowing (TREE_TYPE (sub), elt, > + complain)) > + return error_mark_node; > + tree nc = new_ctor; > + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (nc), > + NULL_TREE, sub); > + if (!TREE_CONSTANT (sub)) > + TREE_CONSTANT (new_ctor) = false; > + } > + } > + len += RAW_DATA_LENGTH (val) - 1; > + continue; > + } > tree sub = convert_like (convs->u.list[ix], val, fn, > argnum, false, false, > /*nested_p=*/true, complain); > @@ -8836,8 +8918,9 @@ convert_like_internal (conversion *convs > TREE_CONSTANT (new_ctor) = false; > } > /* Build up the array. */ > - elttype = cp_build_qualified_type > - (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); > + elttype > + = cp_build_qualified_type (elttype, (cp_type_quals (elttype) > + | TYPE_QUAL_CONST)); > array = build_array_of_n_type (elttype, len); > array = finish_compound_literal (array, new_ctor, complain); > /* This is dubious now, should be blessed by P2752. */ > --- gcc/testsuite/g++.dg/cpp/embed-15.C.jj 2024-12-19 15:07:28.564605983 +0100 > +++ gcc/testsuite/g++.dg/cpp/embed-15.C 2024-12-19 15:08:14.194998077 +0100 > @@ -0,0 +1,35 @@ > +// PR c++/118124 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > + > +namespace std { > +template <class T> struct initializer_list { > +private: > + const T *_M_array; > + __SIZE_TYPE__ _M_len; > +}; > +} > +struct A { > + A (std::initializer_list<char>); > +}; > +A a { > +#embed __FILE__ > +}; > +struct B { > + B (std::initializer_list<unsigned char>); > +}; > +B b { > +#embed __FILE__ > +}; > +struct C { > + C (std::initializer_list<int>); > +}; > +C c { > +#embed __FILE__ > +}; > +struct D { > + D (std::initializer_list<float>); > +}; > +D d { > +#embed __FILE__ > +}; > --- gcc/testsuite/g++.dg/cpp/embed-16.C.jj 2024-12-19 15:09:20.929109016 +0100 > +++ gcc/testsuite/g++.dg/cpp/embed-16.C 2024-12-19 15:11:12.811618467 +0100 > @@ -0,0 +1,18 @@ > +// PR c++/118124 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > +// non-ASCII chars here: áéí > + > +namespace std { > +template <class T> struct initializer_list { > +private: > + const T *_M_array; > + __SIZE_TYPE__ _M_len; > +}; > +} > +struct A { > + A (std::initializer_list<signed char>); > +}; > +A a { > +#embed __FILE__ > +}; // { dg-error "narrowing conversion of '\[0-9]*' from 'int' to 'signed char'" } > --- gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C.jj 2024-12-19 14:52:17.389013179 +0100 > +++ gcc/testsuite/g++.dg/cpp0x/initlist-opt3.C 2024-12-19 15:06:28.652404163 +0100 > @@ -0,0 +1,47 @@ > +// PR c++/118124 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > + > +namespace std { > +template <class T> struct initializer_list { > +private: > + const T *_M_array; > + __SIZE_TYPE__ _M_len; > +}; > +} > +struct A { > + A (std::initializer_list<char>); > +}; > +A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; > +struct B { > + B (std::initializer_list<unsigned char>); > +}; > +B b { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; > +struct C { > + C (std::initializer_list<int>); > +}; > +C c { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; > +struct D { > + D (std::initializer_list<float>); > +}; > +D d { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; > --- gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C.jj 2024-12-19 14:52:46.517612306 +0100 > +++ gcc/testsuite/g++.dg/cpp0x/initlist-opt4.C 2024-12-19 15:06:52.513086275 +0100 > @@ -0,0 +1,20 @@ > +// PR c++/118124 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > + > +namespace std { > +template <class T> struct initializer_list { > +private: > + const T *_M_array; > + __SIZE_TYPE__ _M_len; > +}; > +} > +struct A { > + A (std::initializer_list<signed char>); > +}; > +A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, > + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, > + 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 209, 0, 1, 2, 3, > + 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, > + 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; // { dg-error "narrowing conversion of '209' from 'int' to 'signed char'" } > > > Jakub > ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-01-15 0:52 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2024-12-19 16:07 [PATCH] c++: Fix ICEs with large initializer lists or ones including #embed [PR118124] Jakub Jelinek 2024-12-19 16:52 ` Jason Merrill 2024-12-19 18:01 ` [PATCH] c++, v2: " Jakub Jelinek 2024-12-20 9:24 ` [PATCH] c++, v3: " Jakub Jelinek 2025-01-10 2:30 ` Jason Merrill 2025-01-10 9:21 ` Jakub Jelinek 2025-01-15 0:52 ` Jason Merrill
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).