c++: Inherited constructor template arguments [PR94719]
authorPatrick Palka <ppalka@redhat.com>
Wed, 22 Apr 2020 19:57:39 +0000 (15:57 -0400)
committerPatrick Palka <ppalka@redhat.com>
Wed, 22 Apr 2020 19:57:39 +0000 (15:57 -0400)
My fix for PR94549 broke constraints_satisfied_p in the case where the inherited
constructor decl points to an instantiation of a constructor template coming
from an instantiation of a class template.

This is because the DECL_TI_ARGS of the inherited constructor decl in this case
contains only the innermost level of template arguments (those for the
constructor template), but constraint satisfaction expects to have the full set
of template arguments.  This causes template argument substitution during
constraint satisfaction to fail in various ways.

On the other hand, the DECL_TI_ARGS of the DECL_INHERITED_CTOR is a full set of
template arguments but with the innermost level still in its dependent form,
which is the source of PR94549.  So if we could combine these two sets of
template arguments then we'd be golden.

This patch does just that, by effectively reverting the fix for PR94549 and
instead using add_outermost_template_args to combine the template arguments of
the inherited constructor decl with those of its DECL_INHERITED_CTOR.

gcc/cp/ChangeLog:

PR c++/94719
PR c++/94549
* constraint.cc (satisfy_declaration_constraints): If the inherited
constructor points to an instantiation of a constructor template,
remember and use its attached template arguments.

gcc/testsuite/ChangeLog:

PR c++/94719
PR c++/94549
* g++.dg/cpp2a/concepts-inherit-ctor9.C: New test.

gcc/cp/ChangeLog
gcc/cp/constraint.cc
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor9.C [new file with mode: 0644]

index b298db46714afa77ab472fd1e30055e77e72cf01..7380a20f132ce43cba619118085f97bb692d2ff9 100644 (file)
@@ -1,3 +1,11 @@
+2020-04-22  Patrick Palka  <ppalka@redhat.com>
+
+       PR c++/94719
+       PR c++/94549
+       * constraint.cc (satisfy_declaration_constraints): If the inherited
+       constructor points to an instantiation of a constructor template,
+       remember and use its attached template arguments.
+
 2020-04-22  Jonathan Wakely  <jwakely@redhat.com>
 
        PR translation/94698
index c05fafe5da1bf79925a33826d0a479e9369abba3..06161b8c8c4823a8ba87f22e6cfbe872e45973be 100644 (file)
@@ -2736,12 +2736,17 @@ static tree
 satisfy_declaration_constraints (tree t, subst_info info)
 {
   gcc_assert (DECL_P (t));
+  const tree saved_t = t;
 
-  if (!DECL_TEMPLATE_INFO (t))
-    /* For inherited constructors without template information, consider
-       the original declaration; it has the correct template information
-       attached.  */
-    t = strip_inheriting_ctors (t);
+  /* For inherited constructors, consider the original declaration;
+     it has the correct template information attached. */
+  t = strip_inheriting_ctors (t);
+  tree inh_ctor_targs = NULL_TREE;
+  if (t != saved_t)
+    if (tree ti = DECL_TEMPLATE_INFO (saved_t))
+      /* The inherited constructor points to an instantiation of a constructor
+        template; remember its template arguments.  */
+      inh_ctor_targs = TI_ARGS (ti);
 
   /* Update the declaration for diagnostics.  */
   info.in_decl = t;
@@ -2761,6 +2766,8 @@ satisfy_declaration_constraints (tree t, subst_info info)
       /* The initial parameter mapping is the complete set of
         template arguments substituted into the declaration.  */
       args = TI_ARGS (ti);
+      if (inh_ctor_targs)
+       args = add_outermost_template_args (args, inh_ctor_targs);
     }
   else
     {
index 955418f669a7d85f9ba434ef4c83edec41c36bc9..1115eb769681cb3a26f7f45500dab32a1b5c0c04 100644 (file)
@@ -1,3 +1,9 @@
+2020-04-22  Patrick Palka  <ppalka@redhat.com>
+
+       PR c++/94719
+       PR c++/94549
+       * g++.dg/cpp2a/concepts-inherit-ctor9.C: New test.
+
 2020-04-22  Marek Polacek  <polacek@redhat.com>
 
        PR c++/93807
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor9.C b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor9.C
new file mode 100644 (file)
index 0000000..7d3201b
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/94719
+// { dg-do compile { target concepts } }
+
+template<typename T>
+struct bar
+{
+  template<int N = 5> requires (N == 5)
+  bar() { }
+};
+
+template<typename T>
+struct foo : bar<T>
+{
+  using foo::bar::bar;
+};
+
+void baz()
+{
+  foo<int>{};
+}