Skip to content

Commit 17ef2f6

Browse files
author
Gabor Horvath
committed
[cxx-interop] Make SWIFT_RETURNS_INDEPENDENT_VALUE imply immortal lifetime
The semantics of returning independent value already matches what immortal lifetimes are within Swift. This patch makes sure this annotation works as expected with non-escapable types. rdar://137671642
1 parent 8e2a033 commit 17ef2f6

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3854,6 +3854,18 @@ namespace {
38543854
if (decl->getTemplatedKind() == clang::FunctionDecl::TK_FunctionTemplate)
38553855
return;
38563856

3857+
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
3858+
LifetimeDependenceInfo immortalLifetime(nullptr, nullptr, 0,
3859+
/*isImmortal*/ true);
3860+
if (const auto *funDecl = dyn_cast<FuncDecl>(result))
3861+
if (hasUnsafeAPIAttr(decl) && !funDecl->getResultInterfaceType()->isEscapable()) {
3862+
Impl.SwiftContext.evaluator.cacheOutput(
3863+
LifetimeDependenceInfoRequest{result},
3864+
Impl.SwiftContext.AllocateCopy(lifetimeDependencies));
3865+
lifetimeDependencies.push_back(immortalLifetime);
3866+
return;
3867+
}
3868+
38573869
auto retType = decl->getReturnType();
38583870
auto warnForEscapableReturnType = [&] {
38593871
if (isEscapableAnnotatedType(retType.getTypePtr())) {
@@ -3866,8 +3878,8 @@ namespace {
38663878
};
38673879

38683880
auto swiftParams = result->getParameters();
3869-
bool hasSelf = result->hasImplicitSelfDecl() && !isa<ConstructorDecl>(result);
3870-
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
3881+
bool hasSelf =
3882+
result->hasImplicitSelfDecl() && !isa<ConstructorDecl>(result);
38713883
SmallBitVector inheritLifetimeParamIndicesForReturn(swiftParams->size() +
38723884
hasSelf);
38733885
SmallBitVector scopedLifetimeParamIndicesForReturn(swiftParams->size() +
@@ -3907,8 +3919,7 @@ namespace {
39073919
// Assume default constructed view types have no dependencies.
39083920
if (ctordecl->isDefaultConstructor() &&
39093921
importer::hasNonEscapableAttr(ctordecl->getParent()))
3910-
lifetimeDependencies.push_back(
3911-
LifetimeDependenceInfo(nullptr, nullptr, 0, /*isImmortal*/ true));
3922+
lifetimeDependencies.push_back(immortalLifetime);
39123923
}
39133924
if (lifetimeDependencies.empty()) {
39143925
if (isNonEscapableAnnotatedType(retType.getTypePtr())) {

test/Interop/Cxx/class/nonescapable-lifetimebound.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// RUN: rm -rf %t
22
// RUN: split-file %s %t
3-
// RUN: %target-swift-frontend -typecheck -I %swift_src_root/lib/ClangImporter/SwiftBridging -I %t/Inputs %t/test.swift -enable-experimental-feature NonescapableTypes -cxx-interoperability-mode=default -diagnostic-style llvm 2>&1
43
// RUN: %target-swift-frontend -I %swift_src_root/lib/ClangImporter/SwiftBridging -I %t/Inputs -emit-sil %t/test.swift -enable-experimental-feature NonescapableTypes -cxx-interoperability-mode=default -diagnostic-style llvm 2>&1 | %FileCheck %s
54

65
//--- Inputs/module.modulemap
@@ -77,6 +76,10 @@ private:
7776
const int *member;
7877
};
7978

79+
View returnsImmortal() SWIFT_RETURNS_INDEPENDENT_VALUE {
80+
return View();
81+
}
82+
8083
// CHECK: sil [clang makeOwner] {{.*}}: $@convention(c) () -> Owner
8184
// CHECK: sil [clang getView] {{.*}} : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow 0) @autoreleased View
8285
// CHECK: sil [clang getViewFromFirst] {{.*}} : $@convention(c) (@in_guaranteed Owner, @in_guaranteed Owner) -> @lifetime(borrow 0) @autoreleased View
@@ -86,6 +89,7 @@ private:
8689
// CHECK: sil [clang getViewFromEither] {{.*}} : $@convention(c) (@guaranteed View, @guaranteed View) -> @lifetime(copy 0, copy 1) @autoreleased View
8790
// CHECK: sil [clang View.init] {{.*}} : $@convention(c) () -> @lifetime(immortal) @out View
8891
// CHECK: sil [clang OtherView.init] {{.*}} : $@convention(c) (@guaranteed View) -> @lifetime(copy 0) @out OtherView
92+
// CHECK: sil [clang returnsImmortal] {{.*}} : $@convention(c) () -> @lifetime(immortal) @autoreleased View
8993

9094
//--- test.swift
9195

@@ -102,4 +106,5 @@ public func test() {
102106
let _ = getViewFromEither(v1, v2)
103107
let defaultView = View()
104108
let _ = OtherView(defaultView)
109+
let _ = returnsImmortal()
105110
}

0 commit comments

Comments
 (0)