c++: Fall through for arrays of T vs T cv [PR104996]

If two arrays do not have the exact same element type including
qualification, this could be e.g. f(int (&&)[]) vs. f(int const (&)[]),
which can still be distinguished by the lvalue-rvalue tiebreaker.

By tightening this branch (in accordance with the letter of the Standard) we
fall through to the next branch, which tests whether they have different
element type ignoring qualification and returns 0 in that case; thus we only
actually fall through in the T[...] vs. T cv[...] case, eventually
considering the lvalue-rvalue tiebreaker at the end of compare_ics.

Signed-off-by: Ed Catmur <ed@catmur.uk>

	PR c++/104996

gcc/cp/ChangeLog:

	* call.cc (compare_ics): When comparing list-initialization
	sequences, do not return early.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp0x/initlist129.C: New test.
This commit is contained in:
Ed Catmur 2022-04-18 23:09:04 +01:00 committed by Jason Merrill
parent 67ded3a1f5
commit 5bde80f48b
2 changed files with 8 additions and 5 deletions

View File

@ -11546,12 +11546,9 @@ compare_ics (conversion *ics1, conversion *ics2)
P0388R4.) */
else if (t1->kind == ck_aggr
&& TREE_CODE (t1->type) == ARRAY_TYPE
&& TREE_CODE (t2->type) == ARRAY_TYPE)
&& TREE_CODE (t2->type) == ARRAY_TYPE
&& same_type_p (TREE_TYPE (t1->type), TREE_TYPE (t2->type)))
{
/* The type of the array elements must be the same. */
if (!same_type_p (TREE_TYPE (t1->type), TREE_TYPE (t2->type)))
return 0;
tree n1 = nelts_initialized_by_list_init (t1);
tree n2 = nelts_initialized_by_list_init (t2);
if (tree_int_cst_lt (n1, n2))

View File

@ -0,0 +1,6 @@
// PR c++/104996
// { dg-do compile { target c++11 } }
template<unsigned size> char f(int (&&)[size]);
template<unsigned size> int f(int const (&)[size]);
static_assert(sizeof(f({1, 2, 3})) == 1, "");