public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: enum in generic lambda at global scope [PR105398]
@ 2022-04-26 23:03 Marek Polacek
  2022-04-27 12:24 ` Patrick Palka
  0 siblings, 1 reply; 6+ messages in thread
From: Marek Polacek @ 2022-04-26 23:03 UTC (permalink / raw)
  To: Jason Merrill, GCC Patches

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)
     dependent_p = false;
   else
     dependent_p = instantiation_dependent_expression_p (t);
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-enum2.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-enum2.C
new file mode 100644
index 00000000000..77cf0bb9d02
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-enum2.C
@@ -0,0 +1,15 @@
+// PR c++/105398
+// { dg-do compile { target c++14 } }
+
+auto f = [](auto &&m) {
+    enum E { _,e3,e2,e1,C4,C3,C2,C1 };
+    static constexpr int x_coeffs[3][4] = {
+        {e1,C2,C3,C4},
+        {e2,C1,C3,C4},
+        {e3,C1,C2,C4},
+    };
+};
+
+int main() {
+    f(0);
+}

base-commit: 9ace5d4dab2ab39072b0f07089621a823580f27c
-- 
2.35.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] c++: enum in generic lambda at global scope [PR105398]
  2022-04-26 23:03 [PATCH] c++: enum in generic lambda at global scope [PR105398] Marek Polacek
@ 2022-04-27 12:24 ` Patrick Palka
  2022-04-27 12:59   ` Marek Polacek
  0 siblings, 1 reply; 6+ messages in thread
From: Patrick Palka @ 2022-04-27 12:24 UTC (permalink / raw)
  To: Marek Polacek; +Cc: Jason Merrill, GCC Patches

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?

>      dependent_p = false;
>    else
>      dependent_p = instantiation_dependent_expression_p (t);
> diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-enum2.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-enum2.C
> new file mode 100644
> index 00000000000..77cf0bb9d02
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-enum2.C
> @@ -0,0 +1,15 @@
> +// PR c++/105398
> +// { dg-do compile { target c++14 } }
> +
> +auto f = [](auto &&m) {
> +    enum E { _,e3,e2,e1,C4,C3,C2,C1 };
> +    static constexpr int x_coeffs[3][4] = {
> +        {e1,C2,C3,C4},
> +        {e2,C1,C3,C4},
> +        {e3,C1,C2,C4},
> +    };
> +};
> +
> +int main() {
> +    f(0);
> +}
> 
> base-commit: 9ace5d4dab2ab39072b0f07089621a823580f27c
> -- 
> 2.35.1
> 
> 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] c++: enum in generic lambda at global scope [PR105398]
  2022-04-27 12:24 ` Patrick Palka
@ 2022-04-27 12:59   ` Marek Polacek
  2022-04-27 15:47     ` Jason Merrill
  0 siblings, 1 reply; 6+ messages in thread
From: Marek Polacek @ 2022-04-27 12:59 UTC (permalink / raw)
  To: Patrick Palka; +Cc: Jason Merrill, GCC Patches

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


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] c++: enum in generic lambda at global scope [PR105398]
  2022-04-27 12:59   ` Marek Polacek
@ 2022-04-27 15:47     ` Jason Merrill
  2022-04-27 17:00       ` Marek Polacek
  0 siblings, 1 reply; 6+ messages in thread
From: Jason Merrill @ 2022-04-27 15:47 UTC (permalink / raw)
  To: Marek Polacek, Patrick Palka; +Cc: GCC Patches

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.

Jason


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] c++: enum in generic lambda at global scope [PR105398]
  2022-04-27 15:47     ` Jason Merrill
@ 2022-04-27 17:00       ` Marek Polacek
  2022-04-27 17:01         ` Jason Merrill
  0 siblings, 1 reply; 6+ messages in thread
From: Marek Polacek @ 2022-04-27 17:00 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Patrick Palka, GCC Patches

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


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] c++: enum in generic lambda at global scope [PR105398]
  2022-04-27 17:00       ` Marek Polacek
@ 2022-04-27 17:01         ` Jason Merrill
  0 siblings, 0 replies; 6+ messages in thread
From: Jason Merrill @ 2022-04-27 17:01 UTC (permalink / raw)
  To: Marek Polacek; +Cc: Patrick Palka, GCC Patches

On 4/27/22 13:00, Marek Polacek wrote:
> 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?

Yes.  And the second patch is OK for stage 1.

Jason


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-04-27 17:01 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-26 23:03 [PATCH] c++: enum in generic lambda at global scope [PR105398] Marek Polacek
2022-04-27 12:24 ` Patrick Palka
2022-04-27 12:59   ` Marek Polacek
2022-04-27 15:47     ` Jason Merrill
2022-04-27 17:00       ` Marek Polacek
2022-04-27 17:01         ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).