]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: default template arg, partial ordering [PR105481]
authorJason Merrill <jason@redhat.com>
Thu, 23 Mar 2023 22:20:52 +0000 (18:20 -0400)
committerJason Merrill <jason@redhat.com>
Tue, 18 Apr 2023 20:44:28 +0000 (16:44 -0400)
The default argument code in type_unification_real was assuming that all
targs we've deduced by that point are non-dependent, but that's not the case
for partial ordering.

PR c++/105481

gcc/cp/ChangeLog:

* pt.cc (type_unification_real): Adjust for partial ordering.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/fntmpdefarg-partial1.C: New test.

gcc/cp/pt.cc
gcc/testsuite/g++.dg/cpp0x/fntmpdefarg-partial1.C [new file with mode: 0644]

index a638d30cc7ed93b6583d2dafa5124453fbdff7c2..b5fabe4341ecc2f1bb236dd20bf9499c7764f61d 100644 (file)
@@ -23072,14 +23072,24 @@ type_unification_real (tree tparms,
          return unify_parameter_deduction_failure (explain_p, tparm);
        }
 
+      /* During partial ordering, we deduce dependent template args.  */
+      bool any_dependent_targs = false;
+
       /* Now substitute into the default template arguments.  */
       for (i = 0; i < ntparms; i++)
        {
          tree targ = TREE_VEC_ELT (targs, i);
          tree tparm = TREE_VEC_ELT (tparms, i);
 
-         if (targ || tparm == error_mark_node)
+         if (targ)
+           {
+             if (!any_dependent_targs && dependent_template_arg_p (targ))
+               any_dependent_targs = true;
+             continue;
+           }
+         if (tparm == error_mark_node)
            continue;
+
          tree parm = TREE_VALUE (tparm);
          tree arg = TREE_PURPOSE (tparm);
          reopen_deferring_access_checks (*checks);
@@ -23114,9 +23124,9 @@ type_unification_real (tree tparms,
                 do this substitution without processing_template_decl.  This
                 is important if the default argument contains something that
                 might be instantiation-dependent like access (87480).  */
-             processing_template_decl_sentinel s;
+             processing_template_decl_sentinel s (!any_dependent_targs);
              tree substed = NULL_TREE;
-             if (saw_undeduced == 1)
+             if (saw_undeduced == 1 && !any_dependent_targs)
                {
                  /* First instatiate in template context, in case we still
                     depend on undeduced template parameters.  */
@@ -23139,7 +23149,7 @@ type_unification_real (tree tparms,
                                                 complain, i, NULL_TREE);
              else if (saw_undeduced == 1)
                arg = NULL_TREE;
-             else
+             else if (!any_dependent_targs)
                arg = error_mark_node;
            }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg-partial1.C b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg-partial1.C
new file mode 100644 (file)
index 0000000..2a6783e
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/105481
+// { dg-do compile { target c++11 } }
+
+template<unsigned> struct uint;
+template<unsigned N> uint<N> f(const uint<N> &);
+template<unsigned N, typename T, typename = uint<N>> uint<N> f(T);
+using X = uint<1>;
+X (*fp)(X const &) = f;