[PATCH] PE/COFF: Implement visibility attribute via .drectve

Oleg Tolmatcev <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
On PE/COFF targets (MinGW, Cygwin), the visibility attribute was
previously ignored with a warning.  This patch makes it functional
by emitting -exclude-symbols directives into the .drectve section,
matching Clang's behavior.  The GNU linker already reads and
respects these directives during auto-export, so hidden/internal
symbols are now correctly excluded from DLL exports.

gcc/ChangeLog:

	* config/mingw/winnt.cc (i386_pe_assemble_visibility): Emit
	-exclude-symbols directive into .drectve for VISIBILITY_HIDDEN
	and VISIBILITY_INTERNAL instead of warning.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/visibility-hidden-mingw.c: New test.

Signed-off-by: Oleg Tolmatcev <[email protected]>
---
 gcc/config/mingw/winnt.cc                     | 20 +++++++++-------
 .../gcc.target/i386/visibility-hidden-mingw.c | 24 +++++++++++++++++++
 2 files changed, 36 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/visibility-hidden-mingw.c

diff --git a/gcc/config/mingw/winnt.cc b/gcc/config/mingw/winnt.cc
index 66d7450652..6f2d85b090 100644
--- a/gcc/config/mingw/winnt.cc
+++ b/gcc/config/mingw/winnt.cc
@@ -256,18 +256,22 @@ i386_pe_maybe_mangle_decl_assembler_name (tree decl, tree id)
 
 /* Emit an assembler directive to set symbol for DECL visibility to
    the visibility type VIS, which must not be VISIBILITY_DEFAULT.
-   As for PE there is no hidden support in gas, we just warn for
-   user-specified visibility attributes.  */
+   Emit a -exclude-symbols directive into .drectve, compatible with
+   what Clang emits for hidden visibility on PE/COFF.  */
 
 void
-i386_pe_assemble_visibility (tree decl, int)
+i386_pe_assemble_visibility (tree decl, int vis)
 {
-  if (!decl
-      || !lookup_attribute ("visibility", DECL_ATTRIBUTES (decl)))
+  if (!decl)
     return;
-  if (!DECL_ARTIFICIAL (decl))
-    warning (OPT_Wattributes, "visibility attribute not supported "
-			      "in this configuration; ignored");
+
+  if (vis == VISIBILITY_HIDDEN || vis == VISIBILITY_INTERNAL)
+    {
+      tree id = DECL_ASSEMBLER_NAME (decl);
+      const char *name = IDENTIFIER_POINTER (id);
+      drectve_section ();
+      fprintf (asm_out_file, "\t.ascii \" -exclude-symbols:%s\"\n", name);
+    }
 }
 
 #if !defined (TARGET_AARCH64_MS_ABI)
diff --git a/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw.c b/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw.c
new file mode 100644
index 0000000000..12d792631d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw.c
@@ -0,0 +1,24 @@
+/* { dg-do link { target *-*-mingw* *-*-cygwin* } } */
+/* { dg-require-dll "" } */
+/* { dg-options "-shared -fvisibility=hidden -Wl,--output-def,visibility-hidden-mingw.def" } */
+
+void __attribute__((visibility("default"))) exported_func(void) {}
+void hidden_func(void) {}
+void __attribute__((visibility("hidden"))) explicit_hidden_func(void) {}
+void __attribute__((visibility("internal"))) internal_func(void) {}
+
+/* exported_func has default visibility, so it should be exported.  */
+/* { dg-final { scan-file visibility-hidden-mingw.def "(?n)^\\s*exported_func(?:\\s+@\[0-9\]+)?$" } } */
+
+/* hidden_func gets hidden from -fvisibility=hidden, so it should not be
+   auto-exported.  */
+/* { dg-final { scan-file-not visibility-hidden-mingw.def "(?n)^\\s*hidden_func(?:\\s+@\[0-9\]+)?$" } } */
+
+/* explicit_hidden_func is explicitly hidden, so it should not be
+   auto-exported.  */
+/* { dg-final { scan-file-not visibility-hidden-mingw.def "(?n)^\\s*explicit_hidden_func(?:\\s+@\[0-9\]+)?$" } } */
+
+/* internal_func has internal visibility, so it should not be auto-exported.  */
+/* { dg-final { scan-file-not visibility-hidden-mingw.def "(?n)^\\s*internal_func(?:\\s+@\[0-9\]+)?$" } } */
+
+/* { dg-final { remove-build-file "visibility-hidden-mingw.def" } } */
-- 
2.55.0.windows.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.