From 1e0f37df1b12cd91a6dbb523f5c722f9a961edaa Mon Sep 17 00:00:00 2001 From: Patrick Palka <ppalka@redhat.com> Date: Tue, 18 Jul 2023 09:21:40 -0400 Subject: [PATCH] c++: constrained surrogate call functions [PR110535] We weren't checking constraints on pointer/reference-to-function conversion functions during overload resolution, which caused us to ICE on the first testcase and reject the second testcase. PR c++/110535 gcc/cp/ChangeLog: * call.cc (add_conv_candidate): Check constraints. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-surrogate1.C: New test. * g++.dg/cpp2a/concepts-surrogate2.C: New test. --- gcc/cp/call.cc | 8 ++++++++ gcc/testsuite/g++.dg/cpp2a/concepts-surrogate1.C | 12 ++++++++++++ gcc/testsuite/g++.dg/cpp2a/concepts-surrogate2.C | 14 ++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-surrogate1.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-surrogate2.C diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 976330cd23f8..24f93dd983ca 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -2588,6 +2588,14 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj, if (*candidates && (*candidates)->fn == totype) return NULL; + if (!constraints_satisfied_p (fn)) + { + reason = constraint_failure (); + viable = 0; + return add_candidate (candidates, fn, obj, arglist, len, convs, + access_path, conversion_path, viable, reason, flags); + } + for (i = 0; i < len; ++i) { tree arg, argtype, convert_type = NULL_TREE; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-surrogate1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-surrogate1.C new file mode 100644 index 000000000000..e8481a316568 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-surrogate1.C @@ -0,0 +1,12 @@ +// PR c++/110535 +// { dg-do compile { target c++20 } } + +using F = int(int); + +template<bool B> +struct A { + operator F*() requires B; +}; + +int i = A<true>{}(0); // OK +int j = A<false>{}(0); // { dg-error "no match" } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-surrogate2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-surrogate2.C new file mode 100644 index 000000000000..8bf8364beb72 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-surrogate2.C @@ -0,0 +1,14 @@ +// PR c++/110535 +// { dg-do compile { target c++20 } } + +using F = int(int); +using G = long(int); + +template<bool B> +struct A { + operator F&() requires B; + operator G&() requires (!B); +}; + +int i = A<true>{}(0); // { dg-bogus "ambiguous" } +int j = A<false>{}(0); // { dg-bogus "ambiguous" } -- GitLab