Skip to content

Commit cf3b333

Browse files
author
Gabor Horvath
committed
[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
1 parent f65d41e commit cf3b333

File tree

4 files changed

+94
-1
lines changed

4 files changed

+94
-1
lines changed

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,9 @@ EXPERIMENTAL_FEATURE(WarnUnsafe, true)
412412
/// Import unsafe C and C++ constructs as @unsafe.
413413
EXPERIMENTAL_FEATURE(SafeInterop, true)
414414

415+
/// Ignore resilience errors due to C++ types.
416+
EXPERIMENTAL_FEATURE(AssumeResilientCxxTypes, true)
417+
415418
// Isolated deinit
416419
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(IsolatedDeinit, true)
417420

lib/AST/FeatureSet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ static bool usesFeatureAllowUnsafeAttribute(Decl *decl) {
295295

296296
UNINTERESTING_FEATURE(WarnUnsafe)
297297
UNINTERESTING_FEATURE(SafeInterop)
298+
UNINTERESTING_FEATURE(AssumeResilientCxxTypes)
298299

299300
bool swift::usesFeatureIsolatedDeinit(const Decl *decl) {
300301
if (auto cd = dyn_cast<ClassDecl>(decl)) {

lib/Sema/TypeCheckAccess.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1997,7 +1997,9 @@ swift::getDisallowedOriginKind(const Decl *decl,
19971997
where.getDeclContext()->getAsDecl() &&
19981998
where.getDeclContext()->getAsDecl()->getModuleContext()->isResilient() &&
19991999
decl->hasClangNode() && !decl->getModuleContext()->isSwiftShimsModule() &&
2000-
isFragileClangNode(decl->getClangNode()))
2000+
isFragileClangNode(decl->getClangNode()) &&
2001+
!SF->getASTContext().LangOpts.hasFeature(
2002+
Feature::AssumeResilientCxxTypes))
20012003
return DisallowedOriginKind::FragileCxxAPI;
20022004

20032005
// Report non-public import last as it can be ignored by the caller.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
// 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
4+
5+
//--- Inputs/module.modulemap
6+
module CxxModule {
7+
header "header.h"
8+
requires cplusplus
9+
}
10+
11+
//--- Inputs/header.h
12+
13+
class CxxStruct {
14+
public:
15+
int x; int y;
16+
17+
void method() const;
18+
};
19+
20+
enum class CxxEnum {
21+
A, B
22+
};
23+
24+
template<class T>
25+
class CxxTemplate {
26+
T v;
27+
};
28+
29+
using CxxTemplateInt = CxxTemplate<int>;
30+
31+
class
32+
__attribute__((swift_attr("import_reference")))
33+
__attribute__((swift_attr("retain:immortal")))
34+
__attribute__((swift_attr("release:immortal")))
35+
SingletonReference {
36+
public:
37+
SingletonReference(const SingletonReference &) = delete;
38+
39+
static SingletonReference * _Nonnull create();
40+
41+
void method();
42+
};
43+
44+
CxxStruct createStruct();
45+
46+
void freeCxxFunction();
47+
48+
using BuiltinIntTypealis = int;
49+
50+
//--- test.swift
51+
52+
import CxxModule
53+
54+
public func usesBuiltinIntTypealis() -> BuiltinIntTypealis {
55+
return 21
56+
}
57+
58+
public func usesCxxSingletonReference() -> SingletonReference {
59+
return SingletonReference.create()
60+
}
61+
62+
public func usesCxxStruct(_ x: CxxStruct) {
63+
}
64+
65+
public typealias EnumT = CxxEnum
66+
67+
extension CxxTemplateInt {
68+
func testInternal() {
69+
70+
}
71+
}
72+
73+
extension CxxTemplateInt {
74+
public func testPublicExt() {
75+
}
76+
}
77+
78+
public func publicFuncInternalBody() {
79+
let s = createStruct()
80+
s.method()
81+
}
82+
83+
@inlinable
84+
public func publicFuncPublicBody() {
85+
let value = SingletonReference.create()
86+
value.method()
87+
}

0 commit comments

Comments
 (0)