From 75a110cdc6bb592984eafcebac53f16b2915c371 Mon Sep 17 00:00:00 2001 From: "Henrik G. Olsson" Date: Thu, 18 Dec 2025 21:14:58 -0800 Subject: [PATCH 1/2] [Swiftify] don't attach macro when module does not import stdlib This prevents stuff like memcmp from SwiftShims from being imported with @_SwiftifyImport, which would then result in name lookup errors as it does not import the Swift standard library module. This makes the previous approach to disable safe interop when compiling with -parse-stdlib redundant. irdar://165856959 --- include/swift/Basic/LangOptions.h | 4 --- lib/ClangImporter/SwiftifyDecl.cpp | 28 +++++++++++++++--- lib/Frontend/CompilerInvocation.cpp | 2 -- test/Interop/C/swiftify-import/memcmp.swift | 32 +++++++++++++++++++++ 4 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 test/Interop/C/swiftify-import/memcmp.swift diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index ea1c2bb2bc48a..3b9ad5d877206 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -1137,10 +1137,6 @@ namespace swift { /// ones to apply. bool LoadVersionIndependentAPINotes = false; - /// Whether the importer should skip SafeInteropWrappers, even though the - /// feature is enabled. - bool DisableSafeInteropWrappers = false; - /// Return a hash code of any components from these options that should /// contribute to a Swift Bridging PCH hash. llvm::hash_code getPCHHashComponents() const { diff --git a/lib/ClangImporter/SwiftifyDecl.cpp b/lib/ClangImporter/SwiftifyDecl.cpp index 6d5b40bb655ce..d91b0a4b928ac 100644 --- a/lib/ClangImporter/SwiftifyDecl.cpp +++ b/lib/ClangImporter/SwiftifyDecl.cpp @@ -19,6 +19,7 @@ #include "swift/AST/ASTPrinter.h" #include "swift/AST/Decl.h" #include "swift/AST/DiagnosticsClangImporter.h" +#include "swift/AST/Import.h" #include "swift/AST/ParameterList.h" #include "clang/AST/ASTContext.h" @@ -550,9 +551,22 @@ class SwiftifyProtocolInfoPrinter : public SwiftifyInfoPrinter { } }; +static bool shouldSkipModule(ModuleDecl *M) { + if (M->getName().str() == CLANG_HEADER_MODULE_NAME) { + DLOG("is from bridging header (or C++ namespace)\n"); + return false; + } + + if (M->getImplicitImportInfo().StdlibKind != ImplicitStdlibKind::Stdlib) { + DLOG("module " << M->getNameStr() << " does not import stdlib\n"); + return true; + } + + return false; +} + void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) { - if (!SwiftContext.LangOpts.hasFeature(Feature::SafeInteropWrappers) || - SwiftContext.ClangImporterOpts.DisableSafeInteropWrappers) + if (!SwiftContext.LangOpts.hasFeature(Feature::SafeInteropWrappers)) return; auto ClangDecl = dyn_cast_or_null(MappedDecl->getClangDecl()); if (!ClangDecl) @@ -563,6 +577,9 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) { << MappedDecl->getName().getBaseName().userFacingName() << "')\n"); + if (shouldSkipModule(MappedDecl->getParentModule())) + return; + { UnaliasedInstantiationVisitor visitor; visitor.TraverseType(ClangDecl->getType()); @@ -615,8 +632,7 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) { void ClangImporter::Implementation::swiftifyProtocol( NominalTypeDecl *MappedDecl) { - if (!SwiftContext.LangOpts.hasFeature(Feature::SafeInteropWrappers) || - SwiftContext.ClangImporterOpts.DisableSafeInteropWrappers) + if (!SwiftContext.LangOpts.hasFeature(Feature::SafeInteropWrappers)) return; if (!isa(MappedDecl)) return; @@ -630,6 +646,10 @@ void ClangImporter::Implementation::swiftifyProtocol( DLOG_SCOPE("Checking '" << MappedDecl->getName() << "' protocol for methods with bounds and lifetime info\n"); + + if (shouldSkipModule(MappedDecl->getParentModule())) + return; + llvm::SmallString<128> MacroString; { llvm::raw_svector_ostream out(MacroString); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index d8d1719b1583b..4b5dba26ee228 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -2216,8 +2216,6 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts, ArgList &Args, Opts.LoadVersionIndependentAPINotes |= Args.hasArg(OPT_version_independent_apinotes); - Opts.DisableSafeInteropWrappers |= FrontendOpts.ParseStdlib; - if (FrontendOpts.DisableImplicitModules) Opts.DisableImplicitClangModules = true; diff --git a/test/Interop/C/swiftify-import/memcmp.swift b/test/Interop/C/swiftify-import/memcmp.swift new file mode 100644 index 0000000000000..f1b3df4a8c788 --- /dev/null +++ b/test/Interop/C/swiftify-import/memcmp.swift @@ -0,0 +1,32 @@ +// REQUIRES: swift_feature_SafeInteropWrappers + +// RUN: %empty-directory(%t) +// RUN: split-file %s %t + +// Prevent target SDK decl of memcmp (which may or may not have __sized_by annotations) +// from being picked up as the canonical decl. +// RUN: %empty-directory(%t/sdk) + +// RUN: %target-swift-frontend -emit-module -plugin-path %swift-plugin-dir -I %S/Inputs -enable-experimental-feature SafeInteropWrappers -strict-memory-safety -sdk %t/sdk \ +// RUN: -Xcc -Werror %t/test.swift -import-objc-header %t/test.h -verify -verify-additional-file %t%{fs-sep}test.h -Rmacro-expansions + +// Check that ClangImporter does not try to apply _SwiftifyImport to functions in SwiftShims, +// as it does not import the standard library types. + +//--- test.swift +public func callMemCmp1(_ p1: UnsafeMutableRawBufferPointer, _ p2: UnsafeMutableRawBufferPointer) { + // expected-error@+2{{missing argument for parameter #3 in call}} + // expected-error@+1 2{{cannot convert value of type 'UnsafeMutableRawBufferPointer' to expected argument type 'UnsafeRawPointer'}} + let _ = unsafe memcmp(p1, p2) +} + +public func callMemCmp2(_ p1: UnsafeMutableRawPointer, _ p2: UnsafeMutableRawPointer) { + let _ = unsafe memcmp(p1, p2, 13) +} + +//--- test.h +#include +#define __sized_by(x) __attribute__((__sized_by__(x))) + +// expected-note@+1{{'memcmp' declared here}} +int memcmp(const void * _Nullable __sized_by(n) s1, const void * _Nullable __sized_by(n) s2, size_t n); From 1116884d00de2df55414ad97f1d3437cb48b9a45 Mon Sep 17 00:00:00 2001 From: "Henrik G. Olsson" Date: Fri, 19 Dec 2025 15:14:53 -0800 Subject: [PATCH 2/2] consistent use of %{fs-sep} --- test/Interop/C/swiftify-import/memcmp.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Interop/C/swiftify-import/memcmp.swift b/test/Interop/C/swiftify-import/memcmp.swift index f1b3df4a8c788..b3e4eb89b1584 100644 --- a/test/Interop/C/swiftify-import/memcmp.swift +++ b/test/Interop/C/swiftify-import/memcmp.swift @@ -7,8 +7,8 @@ // from being picked up as the canonical decl. // RUN: %empty-directory(%t/sdk) -// RUN: %target-swift-frontend -emit-module -plugin-path %swift-plugin-dir -I %S/Inputs -enable-experimental-feature SafeInteropWrappers -strict-memory-safety -sdk %t/sdk \ -// RUN: -Xcc -Werror %t/test.swift -import-objc-header %t/test.h -verify -verify-additional-file %t%{fs-sep}test.h -Rmacro-expansions +// RUN: %target-swift-frontend -emit-module -plugin-path %swift-plugin-dir -enable-experimental-feature SafeInteropWrappers -strict-memory-safety -sdk %t/sdk \ +// RUN: -Xcc -Werror %t%{fs-sep}test.swift -import-objc-header %t%{fs-sep}test.h -verify -verify-additional-file %t%{fs-sep}test.h -Rmacro-expansions // Check that ClangImporter does not try to apply _SwiftifyImport to functions in SwiftShims, // as it does not import the standard library types.