c++: Dependent conversion operator in concept [PR94597]
authorPatrick Palka <ppalka@redhat.com>
Tue, 21 Apr 2020 14:56:57 +0000 (10:56 -0400)
committerPatrick Palka <ppalka@redhat.com>
Tue, 21 Apr 2020 14:56:57 +0000 (10:56 -0400)
When building the parameter mapping for an atomic constraint,
find_template_parameters does not spot the template parameter within the
conversion-type-id of a dependent conversion operator, which later leads to an
ICE during substitution when looking up the missing template argument for this
unnoticed template parameter.

gcc/cp/ChangeLog:

PR c++/94597
* pt.c (any_template_parm_r) <case IDENTIFIER_NODE>: New case.  If this
is a conversion operator, visit its TREE_TYPE.

gcc/testsuite/ChangeLog:

PR c++/94597
* g++.dg/cpp2a/concepts-conv2.C: New test.

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp2a/concepts-conv2.C [new file with mode: 0644]

index 81647d4..372fd08 100644 (file)
@@ -1,3 +1,9 @@
+2020-04-21  Patrick Palka  <ppalka@redhat.com>
+
+       PR c++/94597
+       * pt.c (any_template_parm_r) <case IDENTIFIER_NODE>: New case.  If this
+       is a conversion operator, visit its TREE_TYPE.
+
 2020-04-21  Nathan Sidwell  <nathan@acm.org>
 
        * pt.c (tsubst_copy_and_build) [POINTER_PLUS_EXPR]: Check for
index 6f74c27..0fc5b24 100644 (file)
@@ -10529,6 +10529,12 @@ any_template_parm_r (tree t, void *data)
       }
       break;
 
+    case IDENTIFIER_NODE:
+      if (IDENTIFIER_CONV_OP_P (t))
+       /* The conversion-type-id of a conversion operator may be dependent.  */
+       WALK_SUBTREE (TREE_TYPE (t));
+      break;
+
     default:
       break;
     }
index 0de5a47..1f3fb60 100644 (file)
@@ -1,3 +1,8 @@
+2020-04-21  Patrick Palka  <ppalka@redhat.com>
+
+       PR c++/94597
+       * g++.dg/cpp2a/concepts-conv2.C: New test.
+
 2020-04-21  Duan bo  <duanbo3@huawei.com>
 
        PR target/94577
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-conv2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-conv2.C
new file mode 100644 (file)
index 0000000..821042f
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/94597
+// { dg-do compile { target c++2a } }
+
+template <typename b, typename c> concept d = requires(b e) { e.operator c(); };
+
+template <typename f, typename g> requires(d<f, g>) bool equal(f, g);
+
+template <typename h> struct i {
+  i(h);
+  operator h();
+};
+
+static_assert( d<i<float>, float>);
+static_assert(!d<i<float>, int>);
+
+bool fun() {
+  i a(2.0f);
+  return equal(a, 3.0f);
+}