public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-9309] c++: Support exporting using-decls in same namespace as target
@ 2024-03-04 23:33 Nathaniel Shead
  0 siblings, 0 replies; only message in thread
From: Nathaniel Shead @ 2024-03-04 23:33 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:ad0f4ef6f74741ea6178a8b795e49effc2bc2a9c

commit r14-9309-gad0f4ef6f74741ea6178a8b795e49effc2bc2a9c
Author: Nathaniel Shead <nathanieloshead@gmail.com>
Date:   Sun Mar 3 23:48:17 2024 +1100

    c++: Support exporting using-decls in same namespace as target
    
    Currently a using-declaration bringing a name into its own namespace is
    a no-op, except for functions. This prevents people from being able to
    redeclare a name brought in from the GMF as exported, however, which
    this patch fixes.
    
    Apart from marking declarations as exported they are also now marked as
    effectively being in the module purview (due to the using-decl) so that
    they are properly processed, as 'add_binding_entity' assumes that
    declarations not in the module purview cannot possibly be exported.
    
    gcc/cp/ChangeLog:
    
            * name-lookup.cc (walk_module_binding): Remove completed FIXME.
            (do_nonmember_using_decl): Mark redeclared entities as exported
            when needed. Check for re-exporting internal linkage types.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/modules/using-12.C: New test.
            * g++.dg/modules/using-13.h: New test.
            * g++.dg/modules/using-13_a.C: New test.
            * g++.dg/modules/using-13_b.C: New test.
    
    Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>

Diff:
---
 gcc/cp/name-lookup.cc                     | 50 +++++++++++++++++----
 gcc/testsuite/g++.dg/modules/using-12.C   | 73 +++++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/modules/using-13.h   | 16 +++++++
 gcc/testsuite/g++.dg/modules/using-13_a.C | 15 +++++++
 gcc/testsuite/g++.dg/modules/using-13_b.C | 20 +++++++++
 5 files changed, 166 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 6444db3f0eb..dce4caf8981 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -4189,7 +4189,7 @@ walk_module_binding (tree binding, bitmap partitions,
 		     void *data)
 {
   // FIXME: We don't quite deal with using decls naming stat hack
-  // type.  Also using decls exporting something from the same scope.
+  // type.
   tree current = binding;
   unsigned count = 0;
 
@@ -5238,13 +5238,36 @@ do_nonmember_using_decl (name_lookup &lookup, bool fn_scope_p,
     }
   else if (insert_p)
     {
-      value = lookup.value;
-      if (revealing_p && module_exporting_p ())
-	check_can_export_using_decl (value);
+      if (revealing_p
+	  && module_exporting_p ()
+	  && check_can_export_using_decl (lookup.value)
+	  && lookup.value == value
+	  && !DECL_MODULE_EXPORT_P (value))
+	{
+	  /* We're redeclaring the same value, but this time as
+	     newly exported: make sure to mark it as such.  */
+	  if (TREE_CODE (value) == TEMPLATE_DECL)
+	    {
+	      DECL_MODULE_EXPORT_P (value) = true;
+
+	      tree result = DECL_TEMPLATE_RESULT (value);
+	      retrofit_lang_decl (result);
+	      DECL_MODULE_PURVIEW_P (result) = true;
+	      DECL_MODULE_EXPORT_P (result) = true;
+	    }
+	  else
+	    {
+	      retrofit_lang_decl (value);
+	      DECL_MODULE_PURVIEW_P (value) = true;
+	      DECL_MODULE_EXPORT_P (value) = true;
+	    }
+	}
+      else
+	value = lookup.value;
     }
   
   /* Now the type binding.  */
-  if (lookup.type && lookup.type != type)
+  if (lookup.type)
     {
       if (type && !decls_match (lookup.type, type))
 	{
@@ -5253,9 +5276,20 @@ do_nonmember_using_decl (name_lookup &lookup, bool fn_scope_p,
 	}
       else if (insert_p)
 	{
-	  type = lookup.type;
-	  if (revealing_p && module_exporting_p ())
-	    check_can_export_using_decl (type);
+	  if (revealing_p
+	      && module_exporting_p ()
+	      && check_can_export_using_decl (lookup.type)
+	      && lookup.type == type
+	      && !DECL_MODULE_EXPORT_P (type))
+	    {
+	      /* We're redeclaring the same type, but this time as
+		 newly exported: make sure to mark it as such.  */
+	      retrofit_lang_decl (type);
+	      DECL_MODULE_PURVIEW_P (type) = true;
+	      DECL_MODULE_EXPORT_P (type) = true;
+	    }
+	  else
+	    type = lookup.type;
 	}
     }
 
diff --git a/gcc/testsuite/g++.dg/modules/using-12.C b/gcc/testsuite/g++.dg/modules/using-12.C
new file mode 100644
index 00000000000..54eacf7276e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/using-12.C
@@ -0,0 +1,73 @@
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi !bad }
+
+// Like using-10.C, but test exporting names within the same namespace.
+
+export module bad;
+
+// internal linkage
+namespace s {
+  namespace {
+    struct a1 {};  // { dg-message "declared here with internal linkage" }
+
+    template <typename T>
+    struct b1;  // { dg-message "declared here with internal linkage" }
+
+    int x1;  // { dg-message "declared here with internal linkage" }
+
+    template <typename T>
+    T y1;  // { dg-message "declared here with internal linkage" }
+
+    void f1();  // { dg-message "declared here with internal linkage" }
+
+    template <typename T>
+    void g1();  // { dg-message "declared here with internal linkage" }
+
+    export using s::a1;  // { dg-error "does not have external linkage" }
+    export using s::b1;  // { dg-error "does not have external linkage" }
+    export using s::x1;  // { dg-error "does not have external linkage" }
+    export using s::y1;  // { dg-error "does not have external linkage" }
+    export using s::f1;  // { dg-error "does not have external linkage" }
+    export using s::g1;  // { dg-error "does not have external linkage" }
+  }
+}
+
+// module linkage
+namespace m {
+  struct a2 {};  // { dg-message "declared here with module linkage" }
+
+  template <typename T>
+  struct b2;  // { dg-message "declared here with module linkage" }
+
+  int x2;  // { dg-message "declared here with module linkage" }
+
+  template <typename T>
+  T y2;  // { dg-message "declared here with module linkage" }
+
+  void f2();  // { dg-message "declared here with module linkage" }
+
+  template <typename T>
+  void g2();  // { dg-message "declared here with module linkage" }
+
+  export using m::a2;  // { dg-error "does not have external linkage" }
+  export using m::b2;  // { dg-error "does not have external linkage" }
+  export using m::x2;  // { dg-error "does not have external linkage" }
+  export using m::y2;  // { dg-error "does not have external linkage" }
+  export using m::f2;  // { dg-error "does not have external linkage" }
+  export using m::g2;  // { dg-error "does not have external linkage" }
+}
+
+namespace t {
+  using a = int;  // { dg-message "declared here with no linkage" }
+
+  template <typename T>
+  using b = int;  // { dg-message "declared here with no linkage" }
+
+  typedef int c;  // { dg-message "declared here with no linkage" }
+
+  export using t::a;  // { dg-error "does not have external linkage" }
+  export using t::b;  // { dg-error "does not have external linkage" }
+  export using t::c;  // { dg-error "does not have external linkage" }
+}
+
+// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/using-13.h b/gcc/testsuite/g++.dg/modules/using-13.h
new file mode 100644
index 00000000000..b8ef2a11cc4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/using-13.h
@@ -0,0 +1,16 @@
+// Like using-11.h, but additional kinds of declarations.
+
+struct A {};
+
+template <typename> struct B {};
+template <> struct B<int> { using foo = int; };
+template <typename T> struct B<T*> { using bar = T; };
+
+using C = int;
+
+inline int D = 0;
+
+#if __cpp_concepts >= 201907L
+template <typename>
+concept E = true;
+#endif
diff --git a/gcc/testsuite/g++.dg/modules/using-13_a.C b/gcc/testsuite/g++.dg/modules/using-13_a.C
new file mode 100644
index 00000000000..fed33ac2333
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/using-13_a.C
@@ -0,0 +1,15 @@
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi M }
+
+module;
+#include "using-13.h"
+
+export module M;
+export using ::A;
+export using ::B;
+export using ::C;
+export using ::D;
+
+#if __cpp_concepts >= 201907L
+export using ::E;
+#endif
diff --git a/gcc/testsuite/g++.dg/modules/using-13_b.C b/gcc/testsuite/g++.dg/modules/using-13_b.C
new file mode 100644
index 00000000000..49fa09d39ee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/using-13_b.C
@@ -0,0 +1,20 @@
+// { dg-additional-options "-fmodules-ts" }
+
+import M;
+
+int main() {
+  A a;
+
+  // Check all specialisations are correctly exported
+  B<void> b;
+  B<int>::foo b1;
+  B<int*>::bar b2;
+
+  C c;
+
+  auto d = D;
+
+#if __cpp_concepts >= 201907L
+  auto e = E<void>;
+#endif
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-03-04 23:33 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-04 23:33 [gcc r14-9309] c++: Support exporting using-decls in same namespace as target Nathaniel Shead

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).