aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2023-10-05 10:45:00 -0400
committerJason Merrill <jason@redhat.com>2023-10-20 16:27:10 -0400
commitff04531b66102110e1c7fbd3a34d8e42ba7152a8 (patch)
tree92a1a7c836375df6572f5f377a5e2dca733529c3 /gcc
parent084addf8a700fab9222d4127ab8524920d0ca481 (diff)
downloadgcc-ff04531b66102110e1c7fbd3a34d8e42ba7152a8.zip
gcc-ff04531b66102110e1c7fbd3a34d8e42ba7152a8.tar.gz
gcc-ff04531b66102110e1c7fbd3a34d8e42ba7152a8.tar.bz2
c++: fix tourney logic
In r13-3766 I changed the logic at the end of tourney to avoid redundant comparisons, but the change also meant skipping any less-good matches between the champ_compared_to_predecessor candidate and champ itself. This should not be a correctness issue, since we believe that joust is a partial order. But it can lead to missed warnings, as in this testcase. gcc/cp/ChangeLog: * call.cc (tourney): Only skip champ_compared_to_predecessor. gcc/testsuite/ChangeLog: * g++.dg/warn/Wsign-promo1.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/call.cc5
-rw-r--r--gcc/testsuite/g++.dg/warn/Wsign-promo1.C15
2 files changed, 18 insertions, 2 deletions
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 657eca9..a49fde9 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -13227,10 +13227,11 @@ tourney (struct z_candidate *candidates, tsubst_flags_t complain)
been compared to. */
for (challenger = candidates;
- challenger != champ
- && challenger != champ_compared_to_predecessor;
+ challenger != champ;
challenger = challenger->next)
{
+ if (challenger == champ_compared_to_predecessor)
+ continue;
fate = joust (champ, challenger, 0, complain);
if (fate != 1)
return NULL;
diff --git a/gcc/testsuite/g++.dg/warn/Wsign-promo1.C b/gcc/testsuite/g++.dg/warn/Wsign-promo1.C
new file mode 100644
index 0000000..51b76ee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wsign-promo1.C
@@ -0,0 +1,15 @@
+// Check that we get joust warnings from comparing the final champ to a
+// candidate between it and the previous champ.
+
+// { dg-additional-options -Wsign-promo }
+
+struct A { A(int); };
+
+enum E { e };
+
+int f(int, A);
+int f(unsigned, A);
+int f(int, int);
+
+int i = f(e, 42); // { dg-warning "passing 'E'" }
+// { dg-warning "in call to 'int f" "" { target *-*-* } .-1 }