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