public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-2226] c++: fix up caching of level lowered ttps
@ 2023-06-30 19:06 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2023-06-30 19:06 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:db38b285ba61c5b888adc0d117177bfd774c1153

commit r14-2226-gdb38b285ba61c5b888adc0d117177bfd774c1153
Author: Patrick Palka <ppalka@redhat.com>
Date:   Fri Jun 30 15:05:22 2023 -0400

    c++: fix up caching of level lowered ttps
    
    Due to level/depth mismatches between the template parameters of a level
    lowered ttp and the original ttp, the ttp comparison check added by
    r14-418-g0bc2a1dc327af9 never actually holds outside of erroneous cases.
    Moreover, it'd be good to also cache the overall TEMPLATE_TEMPLATE_PARM
    instead of only the TEMPLATE_PARM_INDEX.
    
    It's tricky to cache all level lowered ttps since the result of level
    lowering may depend on more than just the depth of the arguments, e.g.
    for TT in
    
      template<class T>
      struct A {
        template<template<T> class TT> void f();
      }
    
    the substitution T=int yields a different level-lowered ttp than T=char.
    But these kinds of ttps seem to be rare in practice, and "simple" ttps
    that don't depend on outer template parameters are easy enough to cache
    like so.  Unfortunately, this means we're back to expecting a duplicate
    error in nontype12.C again since the ttp in question isn't "simple" so
    caching of the (erroneous) lowered ttp doesn't happen.
    
    gcc/cp/ChangeLog:
    
            * cp-tree.h (TEMPLATE_PARM_DESCENDANTS): Harden.
            (TEMPLATE_TYPE_DESCENDANTS): Define.
            (TEMPLATE_TEMPLATE_PARM_SIMPLE_P): Define.
            * pt.cc (reduce_template_parm_level): Revert
            r14-418-g0bc2a1dc327af9 change.
            (process_template_parm): Set TEMPLATE_TEMPLATE_PARM_SIMPLE_P
            appropriately.
            (uses_outer_template_parms): Determine the outer depth of
            a template template parm without relying on DECL_CONTEXT.
            (tsubst) <case TEMPLATE_TEMPLATE_PARM>: Cache lowering a
            simple template template parm.  Consistently use 'code'.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/template/nontype12.C: Refine and XFAIL the dg-bogus
            duplicate diagnostic check.

Diff:
---
 gcc/cp/cp-tree.h                          | 10 ++++++++-
 gcc/cp/pt.cc                              | 37 ++++++++++++++++++-------------
 gcc/testsuite/g++.dg/template/nontype12.C |  2 +-
 3 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 2faf6faadef..3de0e154c12 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -528,6 +528,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
    5: CLASS_TYPE_P (in RECORD_TYPE and UNION_TYPE)
       ENUM_FIXED_UNDERLYING_TYPE_P (in ENUMERAL_TYPE)
       AUTO_IS_DECLTYPE (in TEMPLATE_TYPE_PARM)
+      TEMPLATE_TEMPLATE_PARM_SIMPLE_P (in TEMPLATE_TEMPLATE_PARM)
    6: TYPE_DEPENDENT_P_VALID
 
    Usage of DECL_LANG_FLAG_?:
@@ -6013,7 +6014,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
 	((template_parm_index*)TEMPLATE_PARM_INDEX_CHECK (NODE))
 #define TEMPLATE_PARM_IDX(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->index)
 #define TEMPLATE_PARM_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->level)
-#define TEMPLATE_PARM_DESCENDANTS(NODE) (TREE_CHAIN (NODE))
+#define TEMPLATE_PARM_DESCENDANTS(NODE) (TREE_CHAIN (TEMPLATE_PARM_INDEX_CHECK (NODE)))
 #define TEMPLATE_PARM_ORIG_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->orig_level)
 #define TEMPLATE_PARM_DECL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->decl)
 #define TEMPLATE_PARM_PARAMETER_PACK(NODE) \
@@ -6031,6 +6032,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
   (TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
 #define TEMPLATE_TYPE_ORIG_LEVEL(NODE) \
   (TEMPLATE_PARM_ORIG_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
+#define TEMPLATE_TYPE_DESCENDANTS(NODE) \
+  (TEMPLATE_PARM_DESCENDANTS (TEMPLATE_TYPE_PARM_INDEX (NODE)))
 #define TEMPLATE_TYPE_DECL(NODE) \
   (TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
 #define TEMPLATE_TYPE_PARAMETER_PACK(NODE) \
@@ -6040,6 +6043,11 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
 #define CLASS_PLACEHOLDER_TEMPLATE(NODE) \
   (DECL_INITIAL (TYPE_NAME (TEMPLATE_TYPE_PARM_CHECK (NODE))))
 
+/* True iff the template parameters of this TEMPLATE_TEMPLATE_PARM don't
+   use any outer template parameters.  */
+#define TEMPLATE_TEMPLATE_PARM_SIMPLE_P(NODE) \
+  (TYPE_LANG_FLAG_5 (TEMPLATE_TEMPLATE_PARM_CHECK (NODE)))
+
 /* Contexts in which auto deduction occurs. These flags are
    used to control diagnostics in do_auto_deduction.  */
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 2b2c598c3a9..d7d774fd9e5 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -220,6 +220,7 @@ static tree enclosing_instantiation_of (tree tctx);
 static void instantiate_body (tree pattern, tree args, tree d, bool nested);
 static tree maybe_dependent_member_ref (tree, tree, tsubst_flags_t, tree);
 static void mark_template_arguments_used (tree, tree);
+static bool uses_outer_template_parms (tree);
 
 /* Make the current scope suitable for access checking when we are
    processing T.  T can be FUNCTION_DECL for instantiated function
@@ -4540,12 +4541,7 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args,
   if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE
       || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index))
 	  != TEMPLATE_PARM_LEVEL (index) - levels)
-      || !(TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM
-	   ? (comp_template_parms
-	      (DECL_TEMPLATE_PARMS (TYPE_NAME (type)),
-	       DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL
-				    (TEMPLATE_PARM_DESCENDANTS (index)))))
-	   : same_type_p (type, TREE_TYPE (TEMPLATE_PARM_DESCENDANTS (index)))))
+      || !same_type_p (type, TREE_TYPE (TEMPLATE_PARM_DESCENDANTS (index))))
     {
       tree orig_decl = TEMPLATE_PARM_DECL (index);
 
@@ -4708,6 +4704,10 @@ process_template_parm (tree list, location_t parm_loc, tree parm,
   DECL_ARTIFICIAL (decl) = 1;
   SET_DECL_TEMPLATE_PARM_P (decl);
 
+  if (TREE_CODE (parm) == TEMPLATE_DECL
+      && !uses_outer_template_parms (parm))
+    TEMPLATE_TEMPLATE_PARM_SIMPLE_P (TREE_TYPE (parm)) = true;
+
   /* Build requirements for the type/template parameter.
      This must be done after SET_DECL_TEMPLATE_PARM_P or
      process_template_parm could fail. */
@@ -10973,7 +10973,11 @@ uses_template_parms_level (tree t, int level)
 static bool
 uses_outer_template_parms (tree decl)
 {
-  int depth = template_class_depth (CP_DECL_CONTEXT (decl));
+  int depth;
+  if (DECL_TEMPLATE_TEMPLATE_PARM_P (decl))
+    depth = TEMPLATE_TYPE_LEVEL (TREE_TYPE (decl)) - 1;
+  else
+    depth = template_class_depth (CP_DECL_CONTEXT (decl));
   if (depth == 0)
     return false;
   if (for_each_template_parm (TREE_TYPE (decl), template_parm_outer_level,
@@ -16219,14 +16223,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 		t = TYPE_MAIN_VARIANT (t);
 	      }
 
-	    if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
-		&& (arg = TEMPLATE_TYPE_PARM_INDEX (t),
-		    r = TEMPLATE_PARM_DESCENDANTS (arg))
-		&& (TEMPLATE_PARM_LEVEL (r)
-		    == TEMPLATE_PARM_LEVEL (arg) - levels))
-	      /* Cache the simple case of lowering a type parameter.  */
-	      r = TREE_TYPE (r);
-	    else
+	    if (tree d = TEMPLATE_TYPE_DESCENDANTS (t))
+	      if (TEMPLATE_PARM_LEVEL (d) == TEMPLATE_TYPE_LEVEL (t) - levels
+		  && (code == TEMPLATE_TYPE_PARM
+		      || TEMPLATE_TEMPLATE_PARM_SIMPLE_P (t)))
+		/* Cache lowering a type parameter or a simple template
+		   template parameter.  */
+		r = TREE_TYPE (d);
+
+	    if (!r)
 	      {
 		r = copy_type (t);
 		TEMPLATE_TYPE_PARM_INDEX (r)
@@ -16237,7 +16242,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 		TYPE_POINTER_TO (r) = NULL_TREE;
 		TYPE_REFERENCE_TO (r) = NULL_TREE;
 
-                if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
+		if (code == TEMPLATE_TYPE_PARM)
 		  if (tree ci = PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t))
 		    /* Propagate constraints on placeholders since they are
 		       only instantiated during satisfaction.  */
diff --git a/gcc/testsuite/g++.dg/template/nontype12.C b/gcc/testsuite/g++.dg/template/nontype12.C
index 6642ffd0a13..9a9c3ac1e66 100644
--- a/gcc/testsuite/g++.dg/template/nontype12.C
+++ b/gcc/testsuite/g++.dg/template/nontype12.C
@@ -4,7 +4,7 @@
 template<typename T> struct A
 {
   template<T> int foo();                        // { dg-error "double" "" { target c++17_down } }
-  template<template<T> class> int bar();        // { dg-bogus {double.*C:7:[^\n]*double} }
+  template<template<T> class> int bar();        // { dg-bogus {double[^\n]*\n[^\n]*C:7:[^\n]*double} "" { xfail c++17_down } }
   // { dg-error "double" "" { target c++17_down } .-1 }
   template<T> struct X;                         // { dg-error "double" "" { target c++17_down } }
 };

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

only message in thread, other threads:[~2023-06-30 19:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-30 19:06 [gcc r14-2226] c++: fix up caching of level lowered ttps 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).