aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Catmur <ed@catmur.uk>2022-04-18 23:09:04 +0100
committerJason Merrill <jason@redhat.com>2022-04-20 10:15:21 -0400
commit5bde80f48bcc594658c788895ad1fd86d0916fc2 (patch)
tree547e53800b8acec04789fbfb7a62fa4f51f501df
parent67ded3a1f5b667b4cb5eb2fee8a031e8e4060a7d (diff)
downloadgcc-5bde80f48bcc594658c788895ad1fd86d0916fc2.zip
gcc-5bde80f48bcc594658c788895ad1fd86d0916fc2.tar.gz
gcc-5bde80f48bcc594658c788895ad1fd86d0916fc2.tar.bz2
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.
-rw-r--r--gcc/cp/call.cc7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist129.C6
2 files changed, 8 insertions, 5 deletions
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 51d8f6c..fa18d7f 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -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))
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist129.C b/gcc/testsuite/g++.dg/cpp0x/initlist129.C
new file mode 100644
index 0000000..4d4faa9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist129.C
@@ -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, "");