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 <nathanielosh...@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" }
-- 
2.42.0

Reply via email to