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

Reply via email to