public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-4112] c++: optimize unifying nested templated classes [PR89231]
@ 2023-09-18 18:55 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2023-09-18 18:55 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:80968d5f4683ffb50dbe8051d10f754d5fd00dfb

commit r14-4112-g80968d5f4683ffb50dbe8051d10f754d5fd00dfb
Author: Patrick Palka <ppalka@redhat.com>
Date:   Mon Sep 18 14:54:45 2023 -0400

    c++: optimize unifying nested templated classes [PR89231]
    
    Since the LHS of a qualified-id is a non-deduced context, it effectively
    means we can't deduce from outer template arguments of a class template
    specialization.  And checking for equality between the TI_TEMPLATE of a
    class specialization parm/arg already implies that the outer template
    arguments are the same.  Hence recursing into outer template arguments
    during unification of class specializations is redundant, so this patch
    makes unify recurse only into innermost arguments.
    
    This incidentally fixes the testcase from PR89231 because there
    more_specialized_partial_inst wrongly considers the two partial
    specializations to be unordered ultimately because unify for identical
    parm=arg=A<Ps...>::Collect<N...> gets confused when it recurses into
    parm=arg={Ps...} since Ps is outside the (innermost) level of tparms
    that we're actually deducing.
    
            PR c++/89231
    
    gcc/cp/ChangeLog:
    
            * pt.cc (try_class_unification): Strengthen TI_TEMPLATE equality
            test by not calling most_general_template.  Only unify the
            innermost levels of template arguments.
            (unify) <case CLASS_TYPE>: Only unify the innermost levels of
            template arguments, and only if the template is primary.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp0x/variadic-partial3.C: New test.

Diff:
---
 gcc/cp/pt.cc                                   | 18 ++++++++++++------
 gcc/testsuite/g++.dg/cpp0x/variadic-partial3.C | 19 +++++++++++++++++++
 2 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 31ff80ea6e7..777ff592789 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -23990,8 +23990,7 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg,
     return NULL_TREE;
   else if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
     /* Matches anything.  */;
-  else if (most_general_template (CLASSTYPE_TI_TEMPLATE (arg))
-	   != most_general_template (CLASSTYPE_TI_TEMPLATE (parm)))
+  else if (CLASSTYPE_TI_TEMPLATE (arg) != CLASSTYPE_TI_TEMPLATE (parm))
     return NULL_TREE;
 
   /* We need to make a new template argument vector for the call to
@@ -24032,8 +24031,10 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg,
   if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
     err = unify_bound_ttp_args (tparms, targs, parm, arg, explain_p);
   else
-    err = unify (tparms, targs, CLASSTYPE_TI_ARGS (parm),
-		 CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE, explain_p);
+    err = unify (tparms, targs,
+		 INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (parm)),
+		 INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (arg)),
+		 UNIFY_ALLOW_NONE, explain_p);
 
   return err ? NULL_TREE : arg;
 }
@@ -25159,8 +25160,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
 	    /* There's no chance of unification succeeding.  */
 	    return unify_type_mismatch (explain_p, parm, arg);
 
-	  return unify (tparms, targs, CLASSTYPE_TI_ARGS (parm),
-			CLASSTYPE_TI_ARGS (t), UNIFY_ALLOW_NONE, explain_p);
+	  if (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
+	    return unify (tparms, targs,
+			  INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (parm)),
+			  INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (t)),
+			  UNIFY_ALLOW_NONE, explain_p);
+	  else
+	    return unify_success (explain_p);
 	}
       else if (!same_type_ignoring_top_level_qualifiers_p (parm, arg))
 	return unify_type_mismatch (explain_p, parm, arg);
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial3.C b/gcc/testsuite/g++.dg/cpp0x/variadic-partial3.C
new file mode 100644
index 00000000000..5af60711320
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial3.C
@@ -0,0 +1,19 @@
+// PR c++/89231
+// { dg-do compile { target c++11 } }
+
+template<class... Ps>
+struct A {
+  template<int... Ns>
+  struct Collect { };
+
+  template<int C, int I = 0, class S = Collect<>>
+  struct Seq;
+
+  template<int C, int I, int... N>
+  struct Seq<C, I, Collect<N...>> : Seq<C - 1, I + 1, Collect<N..., I>> { };
+
+  template<int I, int... N>
+  struct Seq<0, I, Collect<N...>> : Collect<N...> { };
+};
+
+A<int>::Seq<4> test;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-09-18 18:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-18 18:55 [gcc r14-4112] c++: optimize unifying nested templated classes [PR89231] Patrick Palka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).