From c02811d47b6877581388aa3c13fbada1db6aa5df Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Wed, 12 Nov 2025 22:18:17 -0800 Subject: [PATCH 1/2] [Clang mangling] Don't mangle when Clang says not to We have been mangling extern "C" symbols when building with C++ interoperability, leading to incorrectly-mangled names such as _Z6memset that should have been unmangled "memset". Fix this so we get consistent mangling between C and C++ interoperability modes. Fixes rdar://164495210. --- lib/ClangImporter/ClangImporter.cpp | 4 +++- test/Inputs/clang-importer-sdk/usr/include/string.h | 10 ++++++++++ test/Interop/Cxx/extern-c/decls.swift | 9 +++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 test/Interop/Cxx/extern-c/decls.swift diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 6694955b31392..859a75715fee2 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -4759,8 +4759,10 @@ void ClangImporter::Implementation::getMangledName( auto ctorGlobalDecl = clang::GlobalDecl(ctor, clang::CXXCtorType::Ctor_Complete); mangler->mangleCXXName(ctorGlobalDecl, os); - } else { + } else if (mangler->shouldMangleDeclName(clangDecl)) { mangler->mangleName(clangDecl, os); + } else { + os << clangDecl->getName(); } } diff --git a/test/Inputs/clang-importer-sdk/usr/include/string.h b/test/Inputs/clang-importer-sdk/usr/include/string.h index 4c6a4ab2eb2b4..4d73f9e4e7304 100644 --- a/test/Inputs/clang-importer-sdk/usr/include/string.h +++ b/test/Inputs/clang-importer-sdk/usr/include/string.h @@ -7,6 +7,12 @@ #include +#ifdef __cplusplus +extern "C" { + +typedef __SIZE_TYPE__ size_t; +#endif + void* memcpy(void* s1, const void* s2, size_t n); void* memmove(void* s1, const void* s2, size_t n); char* strcpy (char* s1, const char* s2); @@ -30,4 +36,8 @@ void* memset(void* s, int c, size_t n); char* strerror(int errnum); size_t strlen(const char* s); +#ifdef __cplusplus +} +#endif + #endif // SDK_STRING_H diff --git a/test/Interop/Cxx/extern-c/decls.swift b/test/Interop/Cxx/extern-c/decls.swift new file mode 100644 index 0000000000000..75c24c9845ad0 --- /dev/null +++ b/test/Interop/Cxx/extern-c/decls.swift @@ -0,0 +1,9 @@ +// RUN: %target-swift-emit-silgen(mock-sdk: %clang-importer-sdk) %s -I %S/Inputs -import-bridging-header %S/../../../Inputs/clang-importer-sdk/usr/include/string.h -enable-experimental-cxx-interop | %FileCheck %s + + +func zerome(ptr: UnsafeMutablePointer) { + memset(ptr, 0, MemoryLayout.size) +} + +// Verify that the asmname is "memset", not a C++-mangled version +// CHECK: sil [serialized] [asmname "memset"] [clang memset] @$sSo6memsetySvSgAB_s5Int32VSitFTo : $@convention(c) (Optional, Int32, Int) -> Optional From e423d77c79075071abf9e490b41cdf78051dfdb7 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Thu, 13 Nov 2025 06:37:11 -0800 Subject: [PATCH 2/2] Generalize test to also work on Windows --- test/Interop/Cxx/extern-c/Inputs/my-memory.h | 11 +++++++++++ test/Interop/Cxx/extern-c/decls.swift | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 test/Interop/Cxx/extern-c/Inputs/my-memory.h diff --git a/test/Interop/Cxx/extern-c/Inputs/my-memory.h b/test/Interop/Cxx/extern-c/Inputs/my-memory.h new file mode 100644 index 0000000000000..e5fb73e128258 --- /dev/null +++ b/test/Interop/Cxx/extern-c/Inputs/my-memory.h @@ -0,0 +1,11 @@ +#ifdef __cplusplus +extern "C" { +#endif + +typedef __SIZE_TYPE__ size_t; + +void* memset(void* s, int c, size_t n); + +#ifdef __cplusplus +} +#endif diff --git a/test/Interop/Cxx/extern-c/decls.swift b/test/Interop/Cxx/extern-c/decls.swift index 75c24c9845ad0..efa20d351c874 100644 --- a/test/Interop/Cxx/extern-c/decls.swift +++ b/test/Interop/Cxx/extern-c/decls.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-emit-silgen(mock-sdk: %clang-importer-sdk) %s -I %S/Inputs -import-bridging-header %S/../../../Inputs/clang-importer-sdk/usr/include/string.h -enable-experimental-cxx-interop | %FileCheck %s +// RUN: %target-swift-emit-silgen(mock-sdk: %clang-importer-sdk) %s -I %S/Inputs -import-bridging-header %S/Inputs/my-memory.h -enable-experimental-cxx-interop | %FileCheck %s func zerome(ptr: UnsafeMutablePointer) {