Message ID | 6551bdb9.170a0220.9dd60.6ce4@mx.google.com |
---|---|
State | New |
Headers | show |
Series | c++/modules: check mismatching exports for class tags [PR98885] | expand |
On 11/13/23 01:09, Nathaniel Shead wrote: > I happened to be browsing the standard a bit later and noticed that we > incorrectly reject the example given below. > > Bootstrapped on x86_64-pc-linux-gnu; regtesting ongoing but modules.exp > completed with no errors. > > -- >8 -- > > A typedef doesn't create a new entity, and thus should be allowed to be > exported even if it has been previously declared un-exported. See the > example in [module.interface] p6: ok. Could you put a reference to [module.interface]/p6 in the comment though? nathan > > export module M; > struct S { int n; }; > typedef S S; > export typedef S S; // OK, does not redeclare an entity > > PR c++/102341 > > gcc/cp/ChangeLog: > > * decl.cc (duplicate_decls): Allow exporting a redeclaration of > a typedef. > > gcc/testsuite/ChangeLog: > > * g++.dg/modules/export-1.C: Adjust test. > > Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> > --- > gcc/cp/decl.cc | 5 ++++- > gcc/testsuite/g++.dg/modules/export-1.C | 6 +++++- > 2 files changed, 9 insertions(+), 2 deletions(-) > > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc > index bde9bd79d58..5e175d3e835 100644 > --- a/gcc/cp/decl.cc > +++ b/gcc/cp/decl.cc > @@ -2231,7 +2231,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) > } > > tree not_tmpl = STRIP_TEMPLATE (olddecl); > - if (DECL_LANG_SPECIFIC (not_tmpl) && DECL_MODULE_ATTACH_P (not_tmpl)) > + if (DECL_LANG_SPECIFIC (not_tmpl) > + && DECL_MODULE_ATTACH_P (not_tmpl) > + /* Typedefs are not entities and so can be exported later. */ > + && TREE_CODE (olddecl) != TYPE_DECL) > { > if (DECL_MODULE_EXPORT_P (STRIP_TEMPLATE (newdecl)) > && !DECL_MODULE_EXPORT_P (not_tmpl)) > diff --git a/gcc/testsuite/g++.dg/modules/export-1.C b/gcc/testsuite/g++.dg/modules/export-1.C > index 3f93814d270..598814370ec 100644 > --- a/gcc/testsuite/g++.dg/modules/export-1.C > +++ b/gcc/testsuite/g++.dg/modules/export-1.C > @@ -9,8 +9,12 @@ export int x (); // { dg-error "conflicting exporting for declaration" } > int y; > export extern int y; // { dg-error "conflicting exporting for declaration" } > > +// A typedef is not an entity so the following is OK; see [module.interface] example 4 > typedef int z; > -export typedef int z; // { dg-error "conflicting exporting for declaration" } > +export typedef int z; // { dg-bogus "conflicting exporting for declaration" } > + > +template <typename T> using w = T; > +export template <typename T> using w = T; // { dg-error "conflicting exporting for declaration" } > > template <typename T> int f (T); > export template <typename T> int f (T); // { dg-error "conflicting exporting for declaration" }
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index bde9bd79d58..5e175d3e835 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -2231,7 +2231,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) } tree not_tmpl = STRIP_TEMPLATE (olddecl); - if (DECL_LANG_SPECIFIC (not_tmpl) && DECL_MODULE_ATTACH_P (not_tmpl)) + if (DECL_LANG_SPECIFIC (not_tmpl) + && DECL_MODULE_ATTACH_P (not_tmpl) + /* Typedefs are not entities and so can be exported later. */ + && TREE_CODE (olddecl) != TYPE_DECL) { if (DECL_MODULE_EXPORT_P (STRIP_TEMPLATE (newdecl)) && !DECL_MODULE_EXPORT_P (not_tmpl)) diff --git a/gcc/testsuite/g++.dg/modules/export-1.C b/gcc/testsuite/g++.dg/modules/export-1.C index 3f93814d270..598814370ec 100644 --- a/gcc/testsuite/g++.dg/modules/export-1.C +++ b/gcc/testsuite/g++.dg/modules/export-1.C @@ -9,8 +9,12 @@ export int x (); // { dg-error "conflicting exporting for declaration" } int y; export extern int y; // { dg-error "conflicting exporting for declaration" } +// A typedef is not an entity so the following is OK; see [module.interface] example 4 typedef int z; -export typedef int z; // { dg-error "conflicting exporting for declaration" } +export typedef int z; // { dg-bogus "conflicting exporting for declaration" } + +template <typename T> using w = T; +export template <typename T> using w = T; // { dg-error "conflicting exporting for declaration" } template <typename T> int f (T); export template <typename T> int f (T); // { dg-error "conflicting exporting for declaration" }
I happened to be browsing the standard a bit later and noticed that we incorrectly reject the example given below. Bootstrapped on x86_64-pc-linux-gnu; regtesting ongoing but modules.exp completed with no errors. -- >8 -- A typedef doesn't create a new entity, and thus should be allowed to be exported even if it has been previously declared un-exported. See the example in [module.interface] p6: export module M; struct S { int n; }; typedef S S; export typedef S S; // OK, does not redeclare an entity PR c++/102341 gcc/cp/ChangeLog: * decl.cc (duplicate_decls): Allow exporting a redeclaration of a typedef. gcc/testsuite/ChangeLog: * g++.dg/modules/export-1.C: Adjust test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> --- gcc/cp/decl.cc | 5 ++++- gcc/testsuite/g++.dg/modules/export-1.C | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-)