diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 3e41fd4fa313ce55dd8381e42f97e249cf23ae51..d19d09adde43b713b6c4149f0c3c4ed901f9d3d1 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 0000000000000000000000000000000000000000..57eeb85d92adfaa0662317e31e1113709a6d5875 --- /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" }