]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: bad 'this' conversion for nullary memfn [PR106760]
authorPatrick Palka <ppalka@redhat.com>
Fri, 28 Jun 2024 23:45:21 +0000 (19:45 -0400)
committerPatrick Palka <ppalka@redhat.com>
Fri, 28 Jun 2024 23:45:21 +0000 (19:45 -0400)
Here we notice the 'this' conversion for the call f<void>() is bad, so
we correctly defer deduction for the template candidate, but we end up
never adding it to 'bad_cands' since missing_conversion_p for it returns
false (its only argument is 'this' which has already been determined to
be bad).  This is not a huge deal, but it causes us to longer accept the
call with -fpermissive in release builds, and a tree check ICE in checking
builds.

So if we have a non-strictly viable template candidate that has not been
instantiated, then we need to add it to 'bad_cands' even if no argument
conversion is missing.

PR c++/106760

gcc/cp/ChangeLog:

* call.cc (add_candidates): Relax test for adding a candidate
to 'bad_cands' to also accept an uninstantiated template candidate
that has no missing conversions.

gcc/testsuite/ChangeLog:

* g++.dg/ext/conv3.C: New test.

Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/call.cc
gcc/testsuite/g++.dg/ext/conv3.C [new file with mode: 0644]

index 7bbc1fb0c7898f7649cd0562bb6334c5bfe2cc9e..83070b2f633eaf9ac98164f5ce9cac81a809111d 100644 (file)
@@ -6742,7 +6742,8 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
 
       if (cand->viable == -1
          && shortcut_bad_convs
-         && missing_conversion_p (cand))
+         && (missing_conversion_p (cand)
+             || TREE_CODE (cand->fn) == TEMPLATE_DECL))
        {
          /* This candidate has been tentatively marked non-strictly viable,
             and we didn't compute all argument conversions for it (having
diff --git a/gcc/testsuite/g++.dg/ext/conv3.C b/gcc/testsuite/g++.dg/ext/conv3.C
new file mode 100644 (file)
index 0000000..7324d56
--- /dev/null
@@ -0,0 +1,13 @@
+// PR c++/106760
+// { dg-additional-options "-fpermissive" }
+
+struct S {
+  template<class> int f();
+  template<class> int g(...);
+};
+
+int main() {
+  const S s;
+  s.f<void>(); // { dg-warning "discards qualifiers" }
+  s.g<void>(); // { dg-warning "discards qualifiers" }
+}