I think the error message is still a little bit unclear but I couldn't come up with something clearer that was similarly concise and matching the existing style.
(Also I noticed that the linked PR was assigned to Nathan but there hadn't been activity for a while, and I've been looking into these kinds of issues recently anyway so I thought I'd give it a go.) Bootstrapped and regtested on x86_64-pc-linux-gnu. I don't have write access. -- >8 -- Checks for exporting a declaration that was previously declared as not exported is implemented in 'duplicate_decls', but this doesn't handle declarations of classes. This patch adds these checks and slightly adjusts the associated error messages for clarity. PR c++/98885 gcc/cp/ChangeLog: * decl.cc (duplicate_decls): Adjust error message. (xref_tag): Adjust error message. Check exporting decl that is already declared as non-exporting. gcc/testsuite/ChangeLog: * g++.dg/modules/export-1.C: Adjust error messages. Remove xfails for working case. Add new test case. Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> --- gcc/cp/decl.cc | 21 ++++++++++++++++++--- gcc/testsuite/g++.dg/modules/export-1.C | 16 +++++++++------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 4a07c7e879b..bde9bd79d58 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -2236,8 +2236,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) if (DECL_MODULE_EXPORT_P (STRIP_TEMPLATE (newdecl)) && !DECL_MODULE_EXPORT_P (not_tmpl)) { - error ("conflicting exporting declaration %qD", newdecl); - inform (olddecl_loc, "previous declaration %q#D here", olddecl); + auto_diagnostic_group d; + error ("conflicting exporting for declaration %qD", newdecl); + inform (olddecl_loc, + "previously declared here without exporting"); } } else if (DECL_MODULE_EXPORT_P (newdecl)) @@ -16249,11 +16251,24 @@ xref_tag (enum tag_types tag_code, tree name, tree decl = TYPE_NAME (t); if (!module_may_redeclare (decl)) { + auto_diagnostic_group d; error ("cannot declare %qD in a different module", decl); - inform (DECL_SOURCE_LOCATION (decl), "declared here"); + inform (DECL_SOURCE_LOCATION (decl), "previously declared here"); return error_mark_node; } + tree not_tmpl = STRIP_TEMPLATE (decl); + if (DECL_LANG_SPECIFIC (not_tmpl) + && DECL_MODULE_ATTACH_P (not_tmpl) + && !DECL_MODULE_EXPORT_P (not_tmpl) + && module_exporting_p ()) + { + auto_diagnostic_group d; + error ("conflicting exporting for declaration %qD", decl); + inform (DECL_SOURCE_LOCATION (decl), + "previously declared here without exporting"); + } + tree maybe_tmpl = decl; if (CLASS_TYPE_P (t) && CLASSTYPE_IS_TEMPLATE (t)) maybe_tmpl = CLASSTYPE_TI_TEMPLATE (t); diff --git a/gcc/testsuite/g++.dg/modules/export-1.C b/gcc/testsuite/g++.dg/modules/export-1.C index 8ca696ebee0..3f93814d270 100644 --- a/gcc/testsuite/g++.dg/modules/export-1.C +++ b/gcc/testsuite/g++.dg/modules/export-1.C @@ -4,19 +4,21 @@ export module frob; // { dg-module-cmi !frob } int x (); -export int x (); // { dg-error "conflicting exporting declaration" } +export int x (); // { dg-error "conflicting exporting for declaration" } int y; -export extern int y; // { dg-error "conflicting exporting declaration" } +export extern int y; // { dg-error "conflicting exporting for declaration" } typedef int z; -export typedef int z; // { dg-error "conflicting exporting declaration" } +export typedef int z; // { dg-error "conflicting exporting for declaration" } template <typename T> int f (T); -export template <typename T> int f (T); // { dg-error "conflicting exporting declaration" } +export template <typename T> int f (T); // { dg-error "conflicting exporting for declaration" } -// doesn't go via duplicate_decls so we miss this for now class A; -export class A; // { dg-error "conflicting exporting declaration" "" { xfail *-*-* } } +export class A; // { dg-error "conflicting exporting for declaration" } -// { dg-warning "due to errors" "" { target *-*-* } 0 } +template <typename T> struct B; +export template <typename T> struct B {}; // { dg-error "conflicting exporting for declaration" } + +// { dg-warning "due to errors" "" { target *-*-* } 0 } -- 2.42.0