From cf3b333eb66520364d3bbb1d71df18f1222a20a1 Mon Sep 17 00:00:00 2001 From: Gabor Horvath Date: Tue, 8 Oct 2024 14:05:35 +0100 Subject: [PATCH] [cxx-interop] Add flag to assume C++ types are resilient Currently, C++ types cannot appear in resilient interfaces. There are some cases where this is overly restrictive. We plan to improve the logic to detect what types should not appear on resilient moduel boundaries. In the meantime, this PR introduces a flag to disable these errors. Users relying on this flag are on their own, this should only be a temporary workaround until we land further improvements to this diagnostic. rdar://137457118 --- include/swift/Basic/Features.def | 3 + lib/AST/FeatureSet.cpp | 1 + lib/Sema/TypeCheckAccess.cpp | 4 +- .../allow-cxx-api-in-evolving-libraries.swift | 87 +++++++++++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 test/Interop/Cxx/library-evolution/allow-cxx-api-in-evolving-libraries.swift diff --git a/include/swift/Basic/Features.def b/include/swift/Basic/Features.def index e71671c86ba4f..d76c92d302e25 100644 --- a/include/swift/Basic/Features.def +++ b/include/swift/Basic/Features.def @@ -412,6 +412,9 @@ EXPERIMENTAL_FEATURE(WarnUnsafe, true) /// Import unsafe C and C++ constructs as @unsafe. EXPERIMENTAL_FEATURE(SafeInterop, true) +/// Ignore resilience errors due to C++ types. +EXPERIMENTAL_FEATURE(AssumeResilientCxxTypes, true) + // Isolated deinit SUPPRESSIBLE_EXPERIMENTAL_FEATURE(IsolatedDeinit, true) diff --git a/lib/AST/FeatureSet.cpp b/lib/AST/FeatureSet.cpp index b9c267fd0b5d8..ae1647dde24b9 100644 --- a/lib/AST/FeatureSet.cpp +++ b/lib/AST/FeatureSet.cpp @@ -295,6 +295,7 @@ static bool usesFeatureAllowUnsafeAttribute(Decl *decl) { UNINTERESTING_FEATURE(WarnUnsafe) UNINTERESTING_FEATURE(SafeInterop) +UNINTERESTING_FEATURE(AssumeResilientCxxTypes) bool swift::usesFeatureIsolatedDeinit(const Decl *decl) { if (auto cd = dyn_cast(decl)) { diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp index 24484cca3fac6..314a149ad4735 100644 --- a/lib/Sema/TypeCheckAccess.cpp +++ b/lib/Sema/TypeCheckAccess.cpp @@ -1997,7 +1997,9 @@ swift::getDisallowedOriginKind(const Decl *decl, where.getDeclContext()->getAsDecl() && where.getDeclContext()->getAsDecl()->getModuleContext()->isResilient() && decl->hasClangNode() && !decl->getModuleContext()->isSwiftShimsModule() && - isFragileClangNode(decl->getClangNode())) + isFragileClangNode(decl->getClangNode()) && + !SF->getASTContext().LangOpts.hasFeature( + Feature::AssumeResilientCxxTypes)) return DisallowedOriginKind::FragileCxxAPI; // Report non-public import last as it can be ignored by the caller. diff --git a/test/Interop/Cxx/library-evolution/allow-cxx-api-in-evolving-libraries.swift b/test/Interop/Cxx/library-evolution/allow-cxx-api-in-evolving-libraries.swift new file mode 100644 index 0000000000000..94b2a5f823470 --- /dev/null +++ b/test/Interop/Cxx/library-evolution/allow-cxx-api-in-evolving-libraries.swift @@ -0,0 +1,87 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %s %t +// RUN: %target-swift-frontend %t/test.swift -I %t/Inputs -typecheck -enable-library-evolution -enable-experimental-cxx-interop -disable-availability-checking -disable-implicit-cxx-module-import -enable-experimental-feature AssumeResilientCxxTypes -verify + +//--- Inputs/module.modulemap +module CxxModule { + header "header.h" + requires cplusplus +} + +//--- Inputs/header.h + +class CxxStruct { +public: + int x; int y; + + void method() const; +}; + +enum class CxxEnum { + A, B +}; + +template +class CxxTemplate { + T v; +}; + +using CxxTemplateInt = CxxTemplate; + +class +__attribute__((swift_attr("import_reference"))) +__attribute__((swift_attr("retain:immortal"))) +__attribute__((swift_attr("release:immortal"))) +SingletonReference { +public: + SingletonReference(const SingletonReference &) = delete; + + static SingletonReference * _Nonnull create(); + + void method(); +}; + +CxxStruct createStruct(); + +void freeCxxFunction(); + +using BuiltinIntTypealis = int; + +//--- test.swift + +import CxxModule + +public func usesBuiltinIntTypealis() -> BuiltinIntTypealis { + return 21 +} + +public func usesCxxSingletonReference() -> SingletonReference { + return SingletonReference.create() +} + +public func usesCxxStruct(_ x: CxxStruct) { +} + +public typealias EnumT = CxxEnum + +extension CxxTemplateInt { + func testInternal() { + + } +} + +extension CxxTemplateInt { + public func testPublicExt() { + } +} + +public func publicFuncInternalBody() { + let s = createStruct() + s.method() +} + +@inlinable +public func publicFuncPublicBody() { + let value = SingletonReference.create() + value.method() +}