c++: Fix typo in RAW_DATA_CST build_list_conv subsubconv hanling [PR119563]
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. 2025-04-03 Andrew Pinski <quic_apinski@quicinc.com> Jakub Jelinek <jakub@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.
This commit is contained in:
parent
564e4e0819
commit
70bf0ee440
3 changed files with 143 additions and 1 deletions
|
@ -917,7 +917,7 @@ build_list_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
|
|||
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)
|
||||
|
|
63
gcc/testsuite/g++.dg/cpp/embed-26.C
Normal file
63
gcc/testsuite/g++.dg/cpp/embed-26.C
Normal file
|
@ -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 ();
|
||||
}
|
79
gcc/testsuite/g++.dg/cpp0x/pr119563.C
Normal file
79
gcc/testsuite/g++.dg/cpp0x/pr119563.C
Normal file
|
@ -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 ();
|
||||
}
|
Loading…
Add table
Reference in a new issue