Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
28 changes: 24 additions & 4 deletions lib/ClangImporter/SwiftifyDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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<clang::FunctionDecl>(MappedDecl->getClangDecl());
if (!ClangDecl)
Expand All @@ -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());
Expand Down Expand Up @@ -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<ProtocolDecl, ClassDecl>(MappedDecl))
return;
Expand All @@ -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);
Expand Down
2 changes: 0 additions & 2 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
32 changes: 32 additions & 0 deletions test/Interop/C/swiftify-import/memcmp.swift
Original file line number Diff line number Diff line change
@@ -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 -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.

//--- 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 <stddef.h>
#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);