public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: Fix error recovery when redeclaring enum in different module [PR99573]
@ 2024-02-12  2:26 Nathaniel Shead
  2024-02-13 23:12 ` Jason Merrill
  0 siblings, 1 reply; 4+ messages in thread
From: Nathaniel Shead @ 2024-02-12  2:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill, Nathan Sidwell

Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

This ensures that with modules enabled, redeclaring an enum in the wrong
module or with the wrong underlying type no longer ICEs.

The patch also rearranges the order of the checks a little because I
think it's probably more important to note that you can't redeclare the
enum all before complaining about mismatched underlying types etc.

As a drive by this patch also adds some missing diagnostic groups, and
rewords the module redeclaration error message to more closely match the
wording used in other places this check is done.

	PR c++/99573

gcc/cp/ChangeLog:

	* decl.cc (start_enum): Reorder check for redeclaring in module.
	Add missing auto_diagnostic_groups.

gcc/testsuite/ChangeLog:

	* g++.dg/modules/enum-12.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
---
 gcc/cp/decl.cc                         | 31 +++++++++++++++-----------
 gcc/testsuite/g++.dg/modules/enum-12.C | 10 +++++++++
 2 files changed, 28 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/enum-12.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 3e41fd4fa31..f982b5f88de 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -16951,12 +16951,28 @@ start_enum (tree name, tree enumtype, tree underlying_type,
 				     /*tag_scope=*/TAG_how::CURRENT_ONLY,
 				     /*template_header_p=*/false);
 
+  /* Attempt to set the declaring module.  */
+  if (modules_p () && enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
+    {
+      tree decl = TYPE_NAME (enumtype);
+      if (!module_may_redeclare (decl))
+	{
+	  auto_diagnostic_group d;
+	  error ("cannot declare %qD in different module", decl);
+	  inform (DECL_SOURCE_LOCATION (decl), "previously declared here");
+	  enumtype = error_mark_node;
+	}
+      else
+	set_instantiating_module (decl);
+    }
+
   /* In case of a template_decl, the only check that should be deferred
      to instantiation time is the comparison of underlying types.  */
   if (enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
     {
       if (scoped_enum_p != SCOPED_ENUM_P (enumtype))
 	{
+	  auto_diagnostic_group d;
 	  error_at (input_location, "scoped/unscoped mismatch "
 		    "in enum %q#T", enumtype);
 	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
@@ -16965,6 +16981,7 @@ start_enum (tree name, tree enumtype, tree underlying_type,
 	}
       else if (ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) != !! underlying_type)
 	{
+	  auto_diagnostic_group d;
 	  error_at (input_location, "underlying type mismatch "
 		    "in enum %q#T", enumtype);
 	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
@@ -16975,25 +16992,13 @@ start_enum (tree name, tree enumtype, tree underlying_type,
 	       && !same_type_p (underlying_type,
 				ENUM_UNDERLYING_TYPE (enumtype)))
 	{
+	  auto_diagnostic_group d;
 	  error_at (input_location, "different underlying type "
 		    "in enum %q#T", enumtype);
 	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
 		  "previous definition here");
 	  underlying_type = NULL_TREE;
 	}
-
-      if (modules_p ())
-	{
-	  if (!module_may_redeclare (TYPE_NAME (enumtype)))
-	    {
-	      error ("cannot define %qD in different module",
-		     TYPE_NAME (enumtype));
-	      inform (DECL_SOURCE_LOCATION (TYPE_NAME (enumtype)),
-		      "declared here");
-	      enumtype = error_mark_node;
-	    }
-	  set_instantiating_module (TYPE_NAME (enumtype));
-	}
     }
 
   if (!enumtype || TREE_CODE (enumtype) != ENUMERAL_TYPE
diff --git a/gcc/testsuite/g++.dg/modules/enum-12.C b/gcc/testsuite/g++.dg/modules/enum-12.C
new file mode 100644
index 00000000000..57eeb85d92a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/enum-12.C
@@ -0,0 +1,10 @@
+// PR c++/99573
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi !foo }
+
+export module foo;
+namespace std {
+  enum class align_val_t : decltype(sizeof(int)) {};  // { dg-error "different module" }
+}
+
+// { dg-prune-output "not writing module" }
-- 
2.43.0


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

* Re: [PATCH] c++: Fix error recovery when redeclaring enum in different module [PR99573]
  2024-02-12  2:26 [PATCH] c++: Fix error recovery when redeclaring enum in different module [PR99573] Nathaniel Shead
@ 2024-02-13 23:12 ` Jason Merrill
  2024-02-13 23:20   ` Nathaniel Shead
  0 siblings, 1 reply; 4+ messages in thread
From: Jason Merrill @ 2024-02-13 23:12 UTC (permalink / raw)
  To: Nathaniel Shead, gcc-patches; +Cc: Nathan Sidwell

On 2/11/24 21:26, Nathaniel Shead wrote:
> Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
> 
> -- >8 --
> 
> This ensures that with modules enabled, redeclaring an enum in the wrong
> module or with the wrong underlying type no longer ICEs.
> 
> The patch also rearranges the order of the checks a little because I
> think it's probably more important to note that you can't redeclare the
> enum all before complaining about mismatched underlying types etc.
> 
> As a drive by this patch also adds some missing diagnostic groups, and
> rewords the module redeclaration error message to more closely match the
> wording used in other places this check is done.
> 
> 	PR c++/99573
> 
> gcc/cp/ChangeLog:
> 
> 	* decl.cc (start_enum): Reorder check for redeclaring in module.
> 	Add missing auto_diagnostic_groups.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/modules/enum-12.C: New test.
> 
> Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
> ---
>   gcc/cp/decl.cc                         | 31 +++++++++++++++-----------
>   gcc/testsuite/g++.dg/modules/enum-12.C | 10 +++++++++
>   2 files changed, 28 insertions(+), 13 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/modules/enum-12.C
> 
> diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> index 3e41fd4fa31..f982b5f88de 100644
> --- a/gcc/cp/decl.cc
> +++ b/gcc/cp/decl.cc
> @@ -16951,12 +16951,28 @@ start_enum (tree name, tree enumtype, tree underlying_type,
>   				     /*tag_scope=*/TAG_how::CURRENT_ONLY,
>   				     /*template_header_p=*/false);
>   
> +  /* Attempt to set the declaring module.  */
> +  if (modules_p () && enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
> +    {
> +      tree decl = TYPE_NAME (enumtype);
> +      if (!module_may_redeclare (decl))
> +	{
> +	  auto_diagnostic_group d;
> +	  error ("cannot declare %qD in different module", decl);
> +	  inform (DECL_SOURCE_LOCATION (decl), "previously declared here");
> +	  enumtype = error_mark_node;
> +	}
> +      else
> +	set_instantiating_module (decl);
> +    }
> +
>     /* In case of a template_decl, the only check that should be deferred
>        to instantiation time is the comparison of underlying types.  */
>     if (enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
>       {

How about moving the module checks here, instead of a few lines higher, 
where you need to duplicate the ENUMERAL_TYPE condition?

>         if (scoped_enum_p != SCOPED_ENUM_P (enumtype))
>   	{
> +	  auto_diagnostic_group d;
>   	  error_at (input_location, "scoped/unscoped mismatch "
>   		    "in enum %q#T", enumtype);
>   	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
> @@ -16965,6 +16981,7 @@ start_enum (tree name, tree enumtype, tree underlying_type,
>   	}
>         else if (ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) != !! underlying_type)
>   	{
> +	  auto_diagnostic_group d;
>   	  error_at (input_location, "underlying type mismatch "
>   		    "in enum %q#T", enumtype);
>   	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
> @@ -16975,25 +16992,13 @@ start_enum (tree name, tree enumtype, tree underlying_type,
>   	       && !same_type_p (underlying_type,
>   				ENUM_UNDERLYING_TYPE (enumtype)))
>   	{
> +	  auto_diagnostic_group d;
>   	  error_at (input_location, "different underlying type "
>   		    "in enum %q#T", enumtype);
>   	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
>   		  "previous definition here");
>   	  underlying_type = NULL_TREE;
>   	}
> -
> -      if (modules_p ())
> -	{
> -	  if (!module_may_redeclare (TYPE_NAME (enumtype)))
> -	    {
> -	      error ("cannot define %qD in different module",
> -		     TYPE_NAME (enumtype));
> -	      inform (DECL_SOURCE_LOCATION (TYPE_NAME (enumtype)),
> -		      "declared here");
> -	      enumtype = error_mark_node;
> -	    }
> -	  set_instantiating_module (TYPE_NAME (enumtype));
> -	}
>       }
>   
>     if (!enumtype || TREE_CODE (enumtype) != ENUMERAL_TYPE
> diff --git a/gcc/testsuite/g++.dg/modules/enum-12.C b/gcc/testsuite/g++.dg/modules/enum-12.C
> new file mode 100644
> index 00000000000..57eeb85d92a
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/enum-12.C
> @@ -0,0 +1,10 @@
> +// PR c++/99573
> +// { dg-additional-options "-fmodules-ts" }
> +// { dg-module-cmi !foo }
> +
> +export module foo;
> +namespace std {
> +  enum class align_val_t : decltype(sizeof(int)) {};  // { dg-error "different module" }
> +}
> +
> +// { dg-prune-output "not writing module" }


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

* Re: [PATCH] c++: Fix error recovery when redeclaring enum in different module [PR99573]
  2024-02-13 23:12 ` Jason Merrill
@ 2024-02-13 23:20   ` Nathaniel Shead
  2024-02-14  2:45     ` Jason Merrill
  0 siblings, 1 reply; 4+ messages in thread
From: Nathaniel Shead @ 2024-02-13 23:20 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches, Nathan Sidwell

On Tue, Feb 13, 2024 at 06:12:51PM -0500, Jason Merrill wrote:
> On 2/11/24 21:26, Nathaniel Shead wrote:
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
> > 
> > -- >8 --
> > 
> > This ensures that with modules enabled, redeclaring an enum in the wrong
> > module or with the wrong underlying type no longer ICEs.
> > 
> > The patch also rearranges the order of the checks a little because I
> > think it's probably more important to note that you can't redeclare the
> > enum all before complaining about mismatched underlying types etc.
> > 
> > As a drive by this patch also adds some missing diagnostic groups, and
> > rewords the module redeclaration error message to more closely match the
> > wording used in other places this check is done.
> > 
> > 	PR c++/99573
> > 
> > gcc/cp/ChangeLog:
> > 
> > 	* decl.cc (start_enum): Reorder check for redeclaring in module.
> > 	Add missing auto_diagnostic_groups.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > 	* g++.dg/modules/enum-12.C: New test.
> > 
> > Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
> > ---
> >   gcc/cp/decl.cc                         | 31 +++++++++++++++-----------
> >   gcc/testsuite/g++.dg/modules/enum-12.C | 10 +++++++++
> >   2 files changed, 28 insertions(+), 13 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/modules/enum-12.C
> > 
> > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> > index 3e41fd4fa31..f982b5f88de 100644
> > --- a/gcc/cp/decl.cc
> > +++ b/gcc/cp/decl.cc
> > @@ -16951,12 +16951,28 @@ start_enum (tree name, tree enumtype, tree underlying_type,
> >   				     /*tag_scope=*/TAG_how::CURRENT_ONLY,
> >   				     /*template_header_p=*/false);
> > +  /* Attempt to set the declaring module.  */
> > +  if (modules_p () && enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
> > +    {
> > +      tree decl = TYPE_NAME (enumtype);
> > +      if (!module_may_redeclare (decl))
> > +	{
> > +	  auto_diagnostic_group d;
> > +	  error ("cannot declare %qD in different module", decl);
> > +	  inform (DECL_SOURCE_LOCATION (decl), "previously declared here");
> > +	  enumtype = error_mark_node;
> > +	}
> > +      else
> > +	set_instantiating_module (decl);
> > +    }
> > +
> >     /* In case of a template_decl, the only check that should be deferred
> >        to instantiation time is the comparison of underlying types.  */
> >     if (enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
> >       {
> 
> How about moving the module checks here, instead of a few lines higher,
> where you need to duplicate the ENUMERAL_TYPE condition?

So like this?

-- >8 --

This ensures that with modules enabled, redeclaring an enum in the wrong
module or with the wrong underlying type no longer ICEs.

The patch also rearranges the order of the checks a little because I
think it's probably more important to note that you can't redeclare the
enum all before complaining about mismatched underlying types etc.

As a drive by this patch also adds some missing diagnostic groups, and
rewords the module redeclaration error message to more closely match the
wording used in other places this check is done.

	PR c++/99573

gcc/cp/ChangeLog:

	* decl.cc (start_enum): Reorder check for redeclaring in module.
	Add missing auto_diagnostic_groups.

gcc/testsuite/ChangeLog:

	* g++.dg/modules/enum-12.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
---
 gcc/cp/decl.cc                         | 35 +++++++++++++++-----------
 gcc/testsuite/g++.dg/modules/enum-12.C | 10 ++++++++
 2 files changed, 31 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/enum-12.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 3e41fd4fa31..d19d09adde4 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -16955,8 +16955,26 @@ start_enum (tree name, tree enumtype, tree underlying_type,
      to instantiation time is the comparison of underlying types.  */
   if (enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
     {
-      if (scoped_enum_p != SCOPED_ENUM_P (enumtype))
+      /* Attempt to set the declaring module.  */
+      if (modules_p ())
 	{
+	  tree decl = TYPE_NAME (enumtype);
+	  if (!module_may_redeclare (decl))
+	    {
+	      auto_diagnostic_group d;
+	      error ("cannot declare %qD in different module", decl);
+	      inform (DECL_SOURCE_LOCATION (decl), "previously declared here");
+	      enumtype = error_mark_node;
+	    }
+	  else
+	    set_instantiating_module (decl);
+	}
+
+      if (enumtype == error_mark_node)
+	;
+      else if (scoped_enum_p != SCOPED_ENUM_P (enumtype))
+	{
+	  auto_diagnostic_group d;
 	  error_at (input_location, "scoped/unscoped mismatch "
 		    "in enum %q#T", enumtype);
 	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
@@ -16965,6 +16983,7 @@ start_enum (tree name, tree enumtype, tree underlying_type,
 	}
       else if (ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) != !! underlying_type)
 	{
+	  auto_diagnostic_group d;
 	  error_at (input_location, "underlying type mismatch "
 		    "in enum %q#T", enumtype);
 	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
@@ -16975,25 +16994,13 @@ start_enum (tree name, tree enumtype, tree underlying_type,
 	       && !same_type_p (underlying_type,
 				ENUM_UNDERLYING_TYPE (enumtype)))
 	{
+	  auto_diagnostic_group d;
 	  error_at (input_location, "different underlying type "
 		    "in enum %q#T", enumtype);
 	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
 		  "previous definition here");
 	  underlying_type = NULL_TREE;
 	}
-
-      if (modules_p ())
-	{
-	  if (!module_may_redeclare (TYPE_NAME (enumtype)))
-	    {
-	      error ("cannot define %qD in different module",
-		     TYPE_NAME (enumtype));
-	      inform (DECL_SOURCE_LOCATION (TYPE_NAME (enumtype)),
-		      "declared here");
-	      enumtype = error_mark_node;
-	    }
-	  set_instantiating_module (TYPE_NAME (enumtype));
-	}
     }
 
   if (!enumtype || TREE_CODE (enumtype) != ENUMERAL_TYPE
diff --git a/gcc/testsuite/g++.dg/modules/enum-12.C b/gcc/testsuite/g++.dg/modules/enum-12.C
new file mode 100644
index 00000000000..57eeb85d92a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/enum-12.C
@@ -0,0 +1,10 @@
+// PR c++/99573
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi !foo }
+
+export module foo;
+namespace std {
+  enum class align_val_t : decltype(sizeof(int)) {};  // { dg-error "different module" }
+}
+
+// { dg-prune-output "not writing module" }
-- 
2.43.0


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

* Re: [PATCH] c++: Fix error recovery when redeclaring enum in different module [PR99573]
  2024-02-13 23:20   ` Nathaniel Shead
@ 2024-02-14  2:45     ` Jason Merrill
  0 siblings, 0 replies; 4+ messages in thread
From: Jason Merrill @ 2024-02-14  2:45 UTC (permalink / raw)
  To: Nathaniel Shead; +Cc: gcc-patches, Nathan Sidwell

On 2/13/24 18:20, Nathaniel Shead wrote:
> On Tue, Feb 13, 2024 at 06:12:51PM -0500, Jason Merrill wrote:
>> On 2/11/24 21:26, Nathaniel Shead wrote:
>>> Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
>>>
>>> -- >8 --
>>>
>>> This ensures that with modules enabled, redeclaring an enum in the wrong
>>> module or with the wrong underlying type no longer ICEs.
>>>
>>> The patch also rearranges the order of the checks a little because I
>>> think it's probably more important to note that you can't redeclare the
>>> enum all before complaining about mismatched underlying types etc.
>>>
>>> As a drive by this patch also adds some missing diagnostic groups, and
>>> rewords the module redeclaration error message to more closely match the
>>> wording used in other places this check is done.
>>>
>>> 	PR c++/99573
>>>
>>> gcc/cp/ChangeLog:
>>>
>>> 	* decl.cc (start_enum): Reorder check for redeclaring in module.
>>> 	Add missing auto_diagnostic_groups.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>> 	* g++.dg/modules/enum-12.C: New test.
>>>
>>> Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
>>> ---
>>>    gcc/cp/decl.cc                         | 31 +++++++++++++++-----------
>>>    gcc/testsuite/g++.dg/modules/enum-12.C | 10 +++++++++
>>>    2 files changed, 28 insertions(+), 13 deletions(-)
>>>    create mode 100644 gcc/testsuite/g++.dg/modules/enum-12.C
>>>
>>> diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
>>> index 3e41fd4fa31..f982b5f88de 100644
>>> --- a/gcc/cp/decl.cc
>>> +++ b/gcc/cp/decl.cc
>>> @@ -16951,12 +16951,28 @@ start_enum (tree name, tree enumtype, tree underlying_type,
>>>    				     /*tag_scope=*/TAG_how::CURRENT_ONLY,
>>>    				     /*template_header_p=*/false);
>>> +  /* Attempt to set the declaring module.  */
>>> +  if (modules_p () && enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
>>> +    {
>>> +      tree decl = TYPE_NAME (enumtype);
>>> +      if (!module_may_redeclare (decl))
>>> +	{
>>> +	  auto_diagnostic_group d;
>>> +	  error ("cannot declare %qD in different module", decl);
>>> +	  inform (DECL_SOURCE_LOCATION (decl), "previously declared here");
>>> +	  enumtype = error_mark_node;
>>> +	}
>>> +      else
>>> +	set_instantiating_module (decl);
>>> +    }
>>> +
>>>      /* In case of a template_decl, the only check that should be deferred
>>>         to instantiation time is the comparison of underlying types.  */
>>>      if (enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
>>>        {
>>
>> How about moving the module checks here, instead of a few lines higher,
>> where you need to duplicate the ENUMERAL_TYPE condition?
> 
> So like this?

OK.

> -- >8 --
> 
> This ensures that with modules enabled, redeclaring an enum in the wrong
> module or with the wrong underlying type no longer ICEs.
> 
> The patch also rearranges the order of the checks a little because I
> think it's probably more important to note that you can't redeclare the
> enum all before complaining about mismatched underlying types etc.
> 
> As a drive by this patch also adds some missing diagnostic groups, and
> rewords the module redeclaration error message to more closely match the
> wording used in other places this check is done.
> 
> 	PR c++/99573
> 
> gcc/cp/ChangeLog:
> 
> 	* decl.cc (start_enum): Reorder check for redeclaring in module.
> 	Add missing auto_diagnostic_groups.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/modules/enum-12.C: New test.
> 
> Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
> ---
>   gcc/cp/decl.cc                         | 35 +++++++++++++++-----------
>   gcc/testsuite/g++.dg/modules/enum-12.C | 10 ++++++++
>   2 files changed, 31 insertions(+), 14 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/modules/enum-12.C
> 
> diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> index 3e41fd4fa31..d19d09adde4 100644
> --- a/gcc/cp/decl.cc
> +++ b/gcc/cp/decl.cc
> @@ -16955,8 +16955,26 @@ start_enum (tree name, tree enumtype, tree underlying_type,
>        to instantiation time is the comparison of underlying types.  */
>     if (enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
>       {
> -      if (scoped_enum_p != SCOPED_ENUM_P (enumtype))
> +      /* Attempt to set the declaring module.  */
> +      if (modules_p ())
>   	{
> +	  tree decl = TYPE_NAME (enumtype);
> +	  if (!module_may_redeclare (decl))
> +	    {
> +	      auto_diagnostic_group d;
> +	      error ("cannot declare %qD in different module", decl);
> +	      inform (DECL_SOURCE_LOCATION (decl), "previously declared here");
> +	      enumtype = error_mark_node;
> +	    }
> +	  else
> +	    set_instantiating_module (decl);
> +	}
> +
> +      if (enumtype == error_mark_node)
> +	;
> +      else if (scoped_enum_p != SCOPED_ENUM_P (enumtype))
> +	{
> +	  auto_diagnostic_group d;
>   	  error_at (input_location, "scoped/unscoped mismatch "
>   		    "in enum %q#T", enumtype);
>   	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
> @@ -16965,6 +16983,7 @@ start_enum (tree name, tree enumtype, tree underlying_type,
>   	}
>         else if (ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) != !! underlying_type)
>   	{
> +	  auto_diagnostic_group d;
>   	  error_at (input_location, "underlying type mismatch "
>   		    "in enum %q#T", enumtype);
>   	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
> @@ -16975,25 +16994,13 @@ start_enum (tree name, tree enumtype, tree underlying_type,
>   	       && !same_type_p (underlying_type,
>   				ENUM_UNDERLYING_TYPE (enumtype)))
>   	{
> +	  auto_diagnostic_group d;
>   	  error_at (input_location, "different underlying type "
>   		    "in enum %q#T", enumtype);
>   	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
>   		  "previous definition here");
>   	  underlying_type = NULL_TREE;
>   	}
> -
> -      if (modules_p ())
> -	{
> -	  if (!module_may_redeclare (TYPE_NAME (enumtype)))
> -	    {
> -	      error ("cannot define %qD in different module",
> -		     TYPE_NAME (enumtype));
> -	      inform (DECL_SOURCE_LOCATION (TYPE_NAME (enumtype)),
> -		      "declared here");
> -	      enumtype = error_mark_node;
> -	    }
> -	  set_instantiating_module (TYPE_NAME (enumtype));
> -	}
>       }
>   
>     if (!enumtype || TREE_CODE (enumtype) != ENUMERAL_TYPE
> diff --git a/gcc/testsuite/g++.dg/modules/enum-12.C b/gcc/testsuite/g++.dg/modules/enum-12.C
> new file mode 100644
> index 00000000000..57eeb85d92a
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/enum-12.C
> @@ -0,0 +1,10 @@
> +// PR c++/99573
> +// { dg-additional-options "-fmodules-ts" }
> +// { dg-module-cmi !foo }
> +
> +export module foo;
> +namespace std {
> +  enum class align_val_t : decltype(sizeof(int)) {};  // { dg-error "different module" }
> +}
> +
> +// { dg-prune-output "not writing module" }


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

end of thread, other threads:[~2024-02-14  2:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-12  2:26 [PATCH] c++: Fix error recovery when redeclaring enum in different module [PR99573] Nathaniel Shead
2024-02-13 23:12 ` Jason Merrill
2024-02-13 23:20   ` Nathaniel Shead
2024-02-14  2:45     ` 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).