The user label prefix is added by `ASM_OUTPUT_LABELREF()` in assembly; it
doesn't exist yet in `i386_pe_assemble_visibility()`. Old code checked for
a user label prefix and might strip a leading underscore that is genuinely
part of the function name.

This commit deletes the check, and makes `i386_pe_assemble_visibility()`
call `default_strip_name_encoding()` like what is passed for `-export:`.

gcc/ChangeLog:

        * config/mingw/winnt.cc (i386_pe_drectve_name): Delete.
        (i386_pe_assemble_visibility): Call `default_strip_name_encoding()`
        directly.

gcc/testsuite/ChangeLog:

        * gcc.target/i386/visibility-hidden-mingw-32.c: Add new testcases for
        functions whose names start with an underscore.

Signed-off-by: LIU Hao <[email protected]>
---
 gcc/config/mingw/winnt.cc                     | 22 ++-----------------
 .../i386/visibility-hidden-mingw-32.c         |  6 +++++
 2 files changed, 8 insertions(+), 20 deletions(-)

diff --git a/gcc/config/mingw/winnt.cc b/gcc/config/mingw/winnt.cc
index 2e06b0e81462..d2e36b825b02 100644
--- a/gcc/config/mingw/winnt.cc
+++ b/gcc/config/mingw/winnt.cc
@@ -254,24 +254,6 @@ i386_pe_maybe_mangle_decl_assembler_name (tree decl, tree 
id)
  #endif
 -/* Return the symbol spelling used by .drectve exclude-symbols directives.
-   This is the external name without the user label prefix, while preserving
-   calling-convention decoration such as fastcall's leading '@' or a
-   stdcall suffix.  */
-
-static const char *
-i386_pe_drectve_name (tree id)
-{
-  const char *name = targetm.strip_name_encoding (IDENTIFIER_POINTER (id));
-  size_t prefix_len = strlen (user_label_prefix);
-
-  if (prefix_len != 0
-      && strncmp (name, user_label_prefix, prefix_len) == 0)
-    name += prefix_len;
-
-  return name;
-}
-
 /* Emit an assembler directive to set symbol for DECL visibility to
    the visibility type VIS, which must not be VISIBILITY_DEFAULT.
    Emit a -exclude-symbols directive into .drectve, compatible with
@@ -285,8 +267,8 @@ i386_pe_assemble_visibility (tree decl, int vis)
    if (vis == VISIBILITY_HIDDEN || vis == VISIBILITY_INTERNAL)
     {
-      tree id = DECL_ASSEMBLER_NAME (decl);
-      const char *name = i386_pe_drectve_name (id);
+      const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+      name = default_strip_name_encoding (name);
       drectve_section ();
       fprintf (asm_out_file, "\t.ascii \" -exclude-symbols:%s\"\n", name);
     }
diff --git a/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw-32.c b/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw-32.c
index a952c71a013f..65f486b107c4 100644
--- a/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw-32.c
+++ b/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw-32.c
@@ -4,9 +4,15 @@
 void some_cdecl (int, int) {}
 void __attribute__((stdcall)) some_stdcall (int, int) {}
 void __attribute__((fastcall)) some_fastcall (int, int) {}
+void _prefixed_cdecl (int, int) {}
+void __attribute__((stdcall)) _prefixed_stdcall (int, int) {}
+void __attribute__((fastcall)) _prefixed_fastcall (int, int) {}
  /* Hidden visibility on 32-bit PE/COFF drops the user label prefix in
    .drectve, but keeps stdcall and fastcall decoration.  */
 /* { dg-final { scan-assembler {-exclude-symbols:some_cdecl} } } */
 /* { dg-final { scan-assembler {-exclude-symbols:some_stdcall@8} } } */
 /* { dg-final { scan-assembler {-exclude-symbols:@some_fastcall@8} } } */
+/* { dg-final { scan-assembler {-exclude-symbols:_prefixed_cdecl} } } */
+/* { dg-final { scan-assembler {-exclude-symbols:_prefixed_stdcall@8} } } */
+/* { dg-final { scan-assembler {-exclude-symbols:@_prefixed_fastcall@8} } } */
--
2.56.1

From 351601b6598d653cbc12bb1e406af2a9785c023a Mon Sep 17 00:00:00 2001
From: LIU Hao <[email protected]>
Date: Fri, 13 Nov 2026 15:49:30 +0800
Subject: [PATCH 9103] gcc/mingw: Don't check for user label prefix in
 `i386_pe_assemble_visibility()`

The user label prefix is added by `ASM_OUTPUT_LABELREF()` in assembly; it
doesn't exist yet in `i386_pe_assemble_visibility()`. Old code checked for
a user label prefix and might strip a leading underscore that is genuinely
part of the function name.

This commit deletes the check, and makes `i386_pe_assemble_visibility()`
call `default_strip_name_encoding()` like what is passed for `-export:`.

gcc/ChangeLog:

        * config/mingw/winnt.cc (i386_pe_drectve_name): Delete.
        (i386_pe_assemble_visibility): Call `default_strip_name_encoding()`
        directly.

gcc/testsuite/ChangeLog:

        * gcc.target/i386/visibility-hidden-mingw-32.c: Add new testcases for
        functions whose names start with an underscore.

Signed-off-by: LIU Hao <[email protected]>
---
 gcc/config/mingw/winnt.cc                     | 22 ++-----------------
 .../i386/visibility-hidden-mingw-32.c         |  6 +++++
 2 files changed, 8 insertions(+), 20 deletions(-)

diff --git a/gcc/config/mingw/winnt.cc b/gcc/config/mingw/winnt.cc
index 2e06b0e81462..d2e36b825b02 100644
--- a/gcc/config/mingw/winnt.cc
+++ b/gcc/config/mingw/winnt.cc
@@ -254,24 +254,6 @@ i386_pe_maybe_mangle_decl_assembler_name (tree decl, tree 
id)
 
 #endif
 
-/* Return the symbol spelling used by .drectve exclude-symbols directives.
-   This is the external name without the user label prefix, while preserving
-   calling-convention decoration such as fastcall's leading '@' or a
-   stdcall suffix.  */
-
-static const char *
-i386_pe_drectve_name (tree id)
-{
-  const char *name = targetm.strip_name_encoding (IDENTIFIER_POINTER (id));
-  size_t prefix_len = strlen (user_label_prefix);
-
-  if (prefix_len != 0
-      && strncmp (name, user_label_prefix, prefix_len) == 0)
-    name += prefix_len;
-
-  return name;
-}
-
 /* Emit an assembler directive to set symbol for DECL visibility to
    the visibility type VIS, which must not be VISIBILITY_DEFAULT.
    Emit a -exclude-symbols directive into .drectve, compatible with
@@ -285,8 +267,8 @@ i386_pe_assemble_visibility (tree decl, int vis)
 
   if (vis == VISIBILITY_HIDDEN || vis == VISIBILITY_INTERNAL)
     {
-      tree id = DECL_ASSEMBLER_NAME (decl);
-      const char *name = i386_pe_drectve_name (id);
+      const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+      name = default_strip_name_encoding (name);
       drectve_section ();
       fprintf (asm_out_file, "\t.ascii \" -exclude-symbols:%s\"\n", name);
     }
diff --git a/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw-32.c 
b/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw-32.c
index a952c71a013f..65f486b107c4 100644
--- a/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw-32.c
+++ b/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw-32.c
@@ -4,9 +4,15 @@
 void some_cdecl (int, int) {}
 void __attribute__((stdcall)) some_stdcall (int, int) {}
 void __attribute__((fastcall)) some_fastcall (int, int) {}
+void _prefixed_cdecl (int, int) {}
+void __attribute__((stdcall)) _prefixed_stdcall (int, int) {}
+void __attribute__((fastcall)) _prefixed_fastcall (int, int) {}
 
 /* Hidden visibility on 32-bit PE/COFF drops the user label prefix in
    .drectve, but keeps stdcall and fastcall decoration.  */
 /* { dg-final { scan-assembler {-exclude-symbols:some_cdecl} } } */
 /* { dg-final { scan-assembler {-exclude-symbols:some_stdcall@8} } } */
 /* { dg-final { scan-assembler {-exclude-symbols:@some_fastcall@8} } } */
+/* { dg-final { scan-assembler {-exclude-symbols:_prefixed_cdecl} } } */
+/* { dg-final { scan-assembler {-exclude-symbols:_prefixed_stdcall@8} } } */
+/* { dg-final { scan-assembler {-exclude-symbols:@_prefixed_fastcall@8} } } */
-- 
2.56.1

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to