aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2023-07-18 09:21:40 -0400
committerPatrick Palka <ppalka@redhat.com>2023-07-18 09:21:40 -0400
commit1e0f37df1b12cd91a6dbb523f5c722f9a961edaa (patch)
treec5d0e63652a0dafb392478045cddc418c6b83156
parent054e93b8757a2d619a528f7dd1b8580cce13c713 (diff)
downloadgcc-1e0f37df1b12cd91a6dbb523f5c722f9a961edaa.zip
gcc-1e0f37df1b12cd91a6dbb523f5c722f9a961edaa.tar.gz
gcc-1e0f37df1b12cd91a6dbb523f5c722f9a961edaa.tar.bz2
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.
-rw-r--r--gcc/cp/call.cc8
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-surrogate1.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-surrogate2.C14
3 files changed, 34 insertions, 0 deletions
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 976330c..24f93dd 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 0000000..e8481a3
--- /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 0000000..8bf8364
--- /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" }