Skip to content

Commit 76de7ec

Browse files
authored
Merge pull request #78946 from swiftlang/gaborh/fix-calling-convention
[cxx-interop] Make borrowing specifiers more precise
2 parents 136cdee + dd3db51 commit 76de7ec

File tree

4 files changed

+19
-7
lines changed

4 files changed

+19
-7
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2687,14 +2687,18 @@ static ParamDecl *getParameterInfo(ClangImporter::Implementation *impl,
26872687
}
26882688
}
26892689

2690+
// Parameters of type const T& imported as T, make sure we borrow from them
2691+
// when they have lifetime annotations.
2692+
bool isBorrowing = (param->getAttr<clang::LifetimeBoundAttr>() ||
2693+
param->getAttr<clang::LifetimeCaptureByAttr>()) &&
2694+
param->getType()->isReferenceType();
26902695
// Foreign references are already references so they don't need to be passed
26912696
// as inout.
26922697
paramInfo->setSpecifier(
26932698
isConsuming ? ParamSpecifier::Consuming
26942699
: (isInOut ? ParamSpecifier::InOut
2695-
: (param->getAttr<clang::LifetimeBoundAttr>()
2696-
? ParamSpecifier::Borrowing
2697-
: ParamSpecifier::Default)));
2700+
: (isBorrowing ? ParamSpecifier::Borrowing
2701+
: ParamSpecifier::Default)));
26982702
paramInfo->setInterfaceType(swiftParamTy);
26992703
impl->recordImplicitUnwrapForDecl(paramInfo, isParamTypeImplicitlyUnwrapped);
27002704

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ CaptureView getCaptureView(const Owner& owner [[clang::lifetimebound]]) {
111111
// CHECK: sil [clang getViewFromEither] {{.*}} : $@convention(c) (@in_guaranteed Owner, @in_guaranteed Owner) -> @lifetime(borrow 0, borrow 1) @owned View
112112
// CHECK: sil [clang Owner.handOutView] {{.*}} : $@convention(cxx_method) (@in_guaranteed Owner) -> @lifetime(borrow 0) @owned View
113113
// CHECK: sil [clang Owner.handOutView2] {{.*}} : $@convention(cxx_method) (View, @in_guaranteed Owner) -> @lifetime(borrow 1) @owned View
114-
// CHECK: sil [clang getViewFromEither] {{.*}} : $@convention(c) (@guaranteed View, @guaranteed View) -> @lifetime(copy 0, copy 1) @owned View
114+
// CHECK: sil [clang getViewFromEither] {{.*}} : $@convention(c) (View, View) -> @lifetime(copy 0, copy 1) @owned View
115115
// CHECK: sil [clang View.init] {{.*}} : $@convention(c) () -> @lifetime(immortal) @out View
116-
// CHECK: sil [clang OtherView.init] {{.*}} : $@convention(c) (@guaranteed View) -> @lifetime(copy 0) @out OtherView
116+
// CHECK: sil [clang OtherView.init] {{.*}} : $@convention(c) (View) -> @lifetime(copy 0) @out OtherView
117117
// CHECK: sil [clang returnsImmortal] {{.*}} : $@convention(c) () -> @lifetime(immortal) @owned View
118118
// CHECK: sil [clang copyView] {{.*}} : $@convention(c) (View, @lifetime(copy 0) @inout View) -> ()
119119
// CHECK: sil [clang getCaptureView] {{.*}} : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow 0) @owned CaptureView

test/Interop/Cxx/stdlib/Inputs/std-span.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ struct DependsOnSelf {
6262

6363
inline struct SpanBox getStructSpanBox() { return {iarray, iarray, sarray, sarray}; }
6464

65+
struct CaptureByReference {
66+
void set(const std::vector<int>& x [[clang::lifetime_capture_by(this)]]) {
67+
this->x = ConstSpanOfInt(x.data(), x.size());
68+
};
69+
ConstSpanOfInt x;
70+
};
71+
6572
inline void funcWithSafeWrapper(ConstSpanOfInt s [[clang::noescape]]) {}
6673

6774
inline ConstSpanOfInt funcWithSafeWrapper2(ConstSpanOfInt s

test/Interop/Cxx/stdlib/std-span-interface.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ import CxxStdlib
1919
// CHECK-NEXT: @_alwaysEmitIntoClient public mutating func get() -> Span<CInt>
2020
// CHECK-NEXT: mutating func get() -> ConstSpanOfInt
2121

22+
// CHECK: mutating func set(_ x: borrowing std.{{.*}}vector<CInt, std.{{.*}}allocator<CInt>>)
2223
// CHECK: func funcWithSafeWrapper(_ s: ConstSpanOfInt)
23-
// CHECK-NEXT: func funcWithSafeWrapper2(_ s: borrowing ConstSpanOfInt) -> ConstSpanOfInt
24+
// CHECK-NEXT: func funcWithSafeWrapper2(_ s: ConstSpanOfInt) -> ConstSpanOfInt
2425
// CHECK-NEXT: func funcWithSafeWrapper3(_ v: borrowing VecOfInt) -> ConstSpanOfInt
2526
// CHECK: struct X {
2627
// CHECK-NEXT: init()
@@ -29,6 +30,6 @@ import CxxStdlib
2930
// CHECK-NEXT: }
3031
// CHECK-NEXT: @_alwaysEmitIntoClient public func funcWithSafeWrapper(_ s: Span<CInt>)
3132
// CHECK-NEXT: @lifetime(s)
32-
// CHECK-NEXT: @_alwaysEmitIntoClient public func funcWithSafeWrapper2(_ s: borrowing Span<CInt>) -> Span<CInt>
33+
// CHECK-NEXT: @_alwaysEmitIntoClient public func funcWithSafeWrapper2(_ s: Span<CInt>) -> Span<CInt>
3334
// CHECK-NEXT: @lifetime(borrow v)
3435
// CHECK-NEXT: @_alwaysEmitIntoClient public func funcWithSafeWrapper3(_ v: borrowing VecOfInt) -> Span<CInt>

0 commit comments

Comments
 (0)