On Wed, Apr 27, 2022 at 11:47:02AM -0400, Jason Merrill wrote:
> On 4/27/22 08:59, Marek Polacek wrote:
> > 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?
>
> Sounds good to me.
Is the original patch OK for trunk then?
Marek