On Tue, Apr 01, 2025 at 04:31:38PM +0200, Jakub Jelinek wrote: > Hi! > > The following testcase ICEs (the embed one actually doesn't but > dereferences random uninitialized pointer far after allocated memory) > because of a typo. In the RAW_DATA_CST handling of list conversion > where there are conversions to something other than > initializer_list<{{,un}signed ,}char>, the code now calls > implicit_conversion for all the RAW_DATA_CST elements and stores them > into subsubconvs array. > The next loop (done in a separate loop because subsubconvs[0] is > handled differently) attempts to do the > for (i = 0; i < len; ++i) > { > conversion *sub = subconvs[i]; > if (sub->rank > t->rank) > t->rank = sub->rank; > if (sub->user_conv_p) > t->user_conv_p = true; > if (sub->bad_p) > t->bad_p = true; > } > rank/user_conv_p/bad_p merging, but I mistyped the index, the loop > iterates with j iterator and i is subconvs index, so the loop effectively > doesn't do anything interesting except for merging from one of the > subsubconvs element, if lucky within the subsubconvs array, if unlucky > not even from inside of the array. > > The following patch fixes that. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
LGTM. > 2025-04-01 Andrew Pinski <quic_apin...@quicinc.com> > Jakub Jelinek <ja...@redhat.com> > > PR c++/119563 > * call.cc (build_list_conv): Fix a typo in loop gathering > summary information from subsubconvs. > > * g++.dg/cpp0x/pr119563.C: New test. > * g++.dg/cpp/embed-26.C: New test. > > --- gcc/cp/call.cc.jj 2025-03-06 11:08:20.657231238 +0100 > +++ gcc/cp/call.cc 2025-04-01 11:25:14.030321320 +0200 > @@ -917,7 +917,7 @@ build_list_conv (tree type, tree ctor, i > t->rank = cr_exact; > for (j = 0; j < (unsigned) RAW_DATA_LENGTH (val); ++j) > { > - sub = subsubconvs[i]; > + sub = subsubconvs[j]; > if (sub->rank > t->rank) > t->rank = sub->rank; > if (sub->user_conv_p) > --- gcc/testsuite/g++.dg/cpp0x/pr119563.C.jj 2025-04-01 11:14:24.702394749 > +0200 > +++ gcc/testsuite/g++.dg/cpp0x/pr119563.C 2025-04-01 11:13:50.962866358 > +0200 > @@ -0,0 +1,79 @@ > +// PR c++/119563 > +// { dg-do run { target c++11 } } > +// { dg-options "-O2" } > + > +namespace std { > +template <typename T> > +struct initializer_list { > +private: > + T *_M_array; > + decltype (sizeof 0) _M_len; > +public: > + constexpr decltype (sizeof 0) > + size () const noexcept { return _M_len; } > + constexpr const T * > + begin () const noexcept { return _M_array; } > + constexpr const T * > + end () const noexcept { return begin () + size (); } > +}; > +} > + > +struct A {} a; > + > +struct B { > + constexpr B (int x) : B (a, x) {} > + template <typename... T> > + constexpr B (A, T... x) : b(x...) {} > + int b; > +}; > + > +struct C { > + C (std::initializer_list<B> x) > + { > + if (x.size () != 130 + 1024 + 130) > + __builtin_abort (); > + unsigned int i = 1, j = 0; > + for (auto a = x.begin (); a < x.end (); ++a) > + if (a->b != i) > + __builtin_abort (); > + else > + { > + if (j == 129 || j == 129 + 1024) > + i = 0; > + i = (i & 15) + 1; > + ++j; > + } > + c = true; > + } > + bool c; > +}; > + > +#define D 1 + 0, 2 + 0, 3 + 0, 4 + 0, 5 + 0, 6 + 0, 7 + 0, 8 + 0, \ > + 9 + 0, 10 + 0, 11 + 0, 12 + 0, 13 + 0, 14 + 0, 15 + 0, 16 + 0 > +#define E D, D, D, D, D, D, D, D > + > +C c { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, E, E, E, E, E, E, E, E, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, > + 1, 2 }; > + > +int > +main () > +{ > + if (!c.c) > + __builtin_abort (); > +} > --- gcc/testsuite/g++.dg/cpp/embed-26.C.jj 2025-04-01 11:18:56.563595381 > +0200 > +++ gcc/testsuite/g++.dg/cpp/embed-26.C 2025-04-01 11:18:35.444890450 > +0200 > @@ -0,0 +1,63 @@ > +// PR c++/119563 > +// { dg-do run { target c++11 } } > +// { dg-options "-O2" } > + > +namespace std { > +template <typename T> > +struct initializer_list { > +private: > + T *_M_array; > + decltype (sizeof 0) _M_len; > +public: > + constexpr decltype (sizeof 0) > + size () const noexcept { return _M_len; } > + constexpr const T * > + begin () const noexcept { return _M_array; } > + constexpr const T * > + end () const noexcept { return begin () + size (); } > +}; > +} > + > +struct A {} a; > + > +struct B { > + constexpr B (int x) : B (a, x) {} > + template <typename... T> > + constexpr B (A, T... x) : b(x...) {} > + int b; > +}; > + > +struct C { > + C (std::initializer_list<B> x) > + { > + unsigned char buf[] = { > +#embed __FILE__ > + }; > + if (x.size () != 2 * sizeof (buf) + 1024) > + __builtin_abort (); > + unsigned int i = 0; > + for (auto a = x.begin (); a < x.end (); ++a, ++i) > + if (a->b != (i < sizeof (buf) ? buf[i] > + : i < sizeof (buf) + 1024 ? ((i - sizeof (buf)) & 7) + 1 > + : buf[i - sizeof (buf) - 1024])) > + __builtin_abort (); > + c = true; > + } > + bool c; > +}; > + > +#define D 1 + 0, 2 + 0, 3 + 0, 4 + 0, 5 + 0, 6 + 0, 7 + 0, 8 + 0 > +#define E D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D > + > +C c { > +#embed __FILE__ suffix (,) > + E, E, E, E, E, E, E, E, > +#embed __FILE__ > +}; > + > +int > +main () > +{ > + if (!c.c) > + __builtin_abort (); > +} Marek