Re: [PATCH] c++: fix up caching of level lowered ttps

2023-06-29 Thread Jason Merrill via Gcc-patches

On 6/1/23 17:42, Patrick Palka wrote:

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 cache the overall TEMPLATE_TEMPLATE_PARM
instead of just the corresponding 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
   struct A
   {
 template class TT>
 void f();
   }

the substitution T=int yields a different level-lowerd 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 is
not "simple" so caching of the (erroneous) lowered ttp doesn't happen.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?  This reduces memory usage of range-v3's zip.cpp by 1%.

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) : Cache lowering a
simple template template parm.  Consistently use 'code'.

gcc/testsuite/ChangeLog:

* g++.dg/template/nontype12.C: Expect a duplicate error again.
---
  gcc/cp/cp-tree.h  | 10 +-
  gcc/cp/pt.cc  | 37 +--
  gcc/testsuite/g++.dg/template/nontype12.C |  3 +-
  3 files changed, 31 insertions(+), 19 deletions(-)

+++ b/gcc/testsuite/g++.dg/template/nontype12.C
@@ -4,8 +4,7 @@
  template struct A
  {
template int foo();// { dg-error "double" "" { 
target c++17_down } }
-  template class> int bar();// { dg-bogus 
{double.*C:7:[^\n]*double} }


Let's xfail the duplicate error rather than remove the dg-bogus.  OK 
with that change.


Jason



[PATCH] c++: fix up caching of level lowered ttps

2023-06-01 Thread Patrick Palka via Gcc-patches
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 cache the overall TEMPLATE_TEMPLATE_PARM
instead of just the corresponding 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
  struct A
  {
template class TT>
void f();
  }

the substitution T=int yields a different level-lowerd 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 is
not "simple" so caching of the (erroneous) lowered ttp doesn't happen.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?  This reduces memory usage of range-v3's zip.cpp by 1%.

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) : Cache lowering a
simple template template parm.  Consistently use 'code'.

gcc/testsuite/ChangeLog:

* g++.dg/template/nontype12.C: Expect a duplicate error again.
---
 gcc/cp/cp-tree.h  | 10 +-
 gcc/cp/pt.cc  | 37 +--
 gcc/testsuite/g++.dg/template/nontype12.C |  3 +-
 3 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f08e5630a5c..cd762667bec 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -525,6 +525,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_?:
@@ -5991,7 +5992,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) \
@@ -6009,6 +6010,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) \
@@ -6018,6 +6021,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
+   depend on 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 1a32f10b22b..15128cf3c7c 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -219,6 +219,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
@@ -4554,12 +4555,7 @@ reduce_template_parm_level (tree index, tree type, int 
levels, tree args,
   if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE
   || (TEMPLATE_PARM_LEVEL