On Wed, Apr 27, 2022 at 08:24:54AM -0400, Patrick Palka wrote:
> On Tue, 26 Apr 2022, Marek Polacek via Gcc-patches wrote:
> 
> > We crash compiling this test since r11-7993 which changed
> > lookup_template_class_1 so that we only call tsubst_enum when
> > 
> >   !uses_template_parms (current_nonlambda_scope ())
> > 
> > But here current_nonlambda_scope () is the global NAMESPACE_DECL ::, which
> > doesn't have a type, therefore is considered type-dependent.  So we don't
> > call tsubst_enum, and crash in tsubst_copy/CONST_DECL because we didn't
> > find the e1 enumerator.
> > 
> > I don't think any namespace can depend on any template parameter, so
> > this patch tweaks uses_template_parms.
> > 
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/11?
> > 
> >     PR c++/105398
> > 
> > gcc/cp/ChangeLog:
> > 
> >     * pt.cc (uses_template_parms): Return false for any NAMESPACE_DECL.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> >     * g++.dg/cpp1y/lambda-generic-enum2.C: New test.
> > ---
> >  gcc/cp/pt.cc                                      |  2 +-
> >  gcc/testsuite/g++.dg/cpp1y/lambda-generic-enum2.C | 15 +++++++++++++++
> >  2 files changed, 16 insertions(+), 1 deletion(-)
> >  create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-enum2.C
> > 
> > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> > index 3cf1d7af8d2..e785c5db142 100644
> > --- a/gcc/cp/pt.cc
> > +++ b/gcc/cp/pt.cc
> > @@ -10905,7 +10905,7 @@ uses_template_parms (tree t)
> >                || uses_template_parms (TREE_CHAIN (t)));
> >    else if (TREE_CODE (t) == TYPE_DECL)
> >      dependent_p = dependent_type_p (TREE_TYPE (t));
> > -  else if (t == error_mark_node)
> > +  else if (t == error_mark_node || TREE_CODE (t) == NAMESPACE_DECL)
> 
> LGTM.  In passing, perhaps we should move this t == error_mark_node test
> to the beginning of the function alongside the t == NULL_TREE test?

Thanks, yeah, maybe.  I also don't like the separate declaration of
saved_processing_template_decl, the return type, but I've resisted cleaning
that up, otherwise I never know when to stop.  But here's a version with more
cleanups:

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e9a3d09ac4c..d0ebbb7a196 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7311,7 +7311,7 @@ extern tree lookup_template_class         (tree, tree, 
tree, tree,
                                                 int, tsubst_flags_t);
 extern tree lookup_template_function           (tree, tree);
 extern tree lookup_template_variable           (tree, tree);
-extern int uses_template_parms                 (tree);
+extern bool uses_template_parms                        (tree);
 extern bool uses_template_parms_level          (tree, int);
 extern bool in_template_function               (void);
 extern bool need_generic_capture               (void);
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 3cf1d7af8d2..dc5b9938f2c 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -10884,35 +10884,30 @@ find_template_parameters (tree t, tree ctx_parms)
 
 /* Returns true if T depends on any template parameter.  */
 
-int
+bool
 uses_template_parms (tree t)
 {
-  if (t == NULL_TREE)
+  if (t == NULL_TREE || t == error_mark_node)
     return false;
 
-  bool dependent_p;
-  int saved_processing_template_decl;
+  /* Namespaces can't depend on any template parameters.  */
+  if (TREE_CODE (t) == NAMESPACE_DECL)
+    return false;
+
+  processing_template_decl_sentinel ptds (/*reset*/false);
+  ++processing_template_decl;
 
-  saved_processing_template_decl = processing_template_decl;
-  if (!saved_processing_template_decl)
-    processing_template_decl = 1;
   if (TYPE_P (t))
-    dependent_p = dependent_type_p (t);
+    return dependent_type_p (t);
   else if (TREE_CODE (t) == TREE_VEC)
-    dependent_p = any_dependent_template_arguments_p (t);
+    return any_dependent_template_arguments_p (t);
   else if (TREE_CODE (t) == TREE_LIST)
-    dependent_p = (uses_template_parms (TREE_VALUE (t))
-                  || uses_template_parms (TREE_CHAIN (t)));
+    return (uses_template_parms (TREE_VALUE (t))
+           || uses_template_parms (TREE_CHAIN (t)));
   else if (TREE_CODE (t) == TYPE_DECL)
-    dependent_p = dependent_type_p (TREE_TYPE (t));
-  else if (t == error_mark_node)
-    dependent_p = false;
+    return dependent_type_p (TREE_TYPE (t));
   else
-    dependent_p = instantiation_dependent_expression_p (t);
-
-  processing_template_decl = saved_processing_template_decl;
-
-  return dependent_p;
+    return instantiation_dependent_expression_p (t);
 }
 
 /* Returns true iff we're processing an incompletely instantiated function


Maybe go with the original patch for GCC 12 and leave the cleanups for GCC 13?

Marek

Reply via email to