Skip to content

Commit 861d368

Browse files
committed
[cxx-interop] Fix inline operators for address-only types.
1 parent c6a266e commit 861d368

File tree

7 files changed

+72
-9
lines changed

7 files changed

+72
-9
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1579,13 +1579,27 @@ class DestructureInputs {
15791579
// Add any leading foreign parameters.
15801580
maybeAddForeignParameters();
15811581

1582+
bool isCxxOperator = origType.isCXXMethod() &&
1583+
origType.getCXXMethod()->isOverloadedOperator();
1584+
15821585
// Process all the non-self parameters.
15831586
for (unsigned i = 0; i != numNonSelfParams; ++i) {
15841587
auto ty = params[i].getParameterType();
15851588
auto eltPattern = origType.getFunctionParamType(i);
15861589
auto flags = params[i].getParameterFlags();
1590+
bool forSelf = false;
1591+
1592+
// If we have an inline operator, when it was imported, it was turned
1593+
// from a method into a static function. So, we need to shift over the
1594+
// params by one and use "self" as the first param's type.
1595+
if (isCxxOperator) {
1596+
if (i == 0)
1597+
forSelf = true;
1598+
else if (i == 1)
1599+
NextOrigParamIndex--;
1600+
}
15871601

1588-
visit(flags.getValueOwnership(), /*forSelf=*/false, eltPattern, ty,
1602+
visit(flags.getValueOwnership(), forSelf, eltPattern, ty,
15891603
silRepresentation, flags.isNoDerivative());
15901604
}
15911605

test/Interop/Cxx/operators/Inputs/member-inline.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,14 @@ struct IntBox {
66
IntBox operator+(IntBox rhs) { return IntBox{.value = value + rhs.value}; }
77
};
88

9+
struct AddressOnlyIntWrapper {
10+
int value;
11+
AddressOnlyIntWrapper(int value) : value(value) {}
12+
AddressOnlyIntWrapper(AddressOnlyIntWrapper const &other)
13+
: value(other.value) {}
14+
AddressOnlyIntWrapper operator-(AddressOnlyIntWrapper rhs) {
15+
return AddressOnlyIntWrapper(value - rhs.value);
16+
}
17+
};
18+
919
#endif

test/Interop/Cxx/operators/member-inline-irgen.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,17 @@
55

66
import MemberInline
77

8-
public func add(_ lhs: inout IntBox, _ rhs: IntBox) -> IntBox { lhs + rhs }
9-
8+
// CHECK-LABEL: define {{.*i32|i64}} @"$s4main3addySo6IntBoxVADz_ADtF"
109
// CHECK: call [[RES:i32|i64]] [[NAME:@(_ZN6IntBoxplES_|"\?\?HIntBox@@QEAA\?AU0@U0@@Z")]](%struct.IntBox* {{%[0-9]+}}, {{i32|\[1 x i32\]|i64|%struct.IntBox\* byval align 4}} {{%[0-9]+}})
10+
// CHECK: ret [[RES]]
11+
1112
// CHECK: define linkonce_odr [[RES]] [[NAME]](%struct.IntBox* %this, {{i32 %rhs.coerce|\[1 x i32\] %rhs.coerce|i64 %rhs.coerce|%struct.IntBox\* byval\(%struct.IntBox\) align 4 %rhs}})
13+
public func add(_ lhs: inout IntBox, _ rhs: IntBox) -> IntBox { lhs + rhs }
14+
15+
// CHECK-LABEL: define {{.*}}void @"$s4main24subAddressOnlyIntWrapperySo0cdeF0VADz_ADtF"
16+
// CHECK: call void [[NAME:@(_ZN21AddressOnlyIntWrappermiES_|"\?\?GAddressOnlyIntWrapper@@QEAA\?AU0@U0@@Z")]](%struct.AddressOnlyIntWrapper* {{%[0-9]+}}, %struct.AddressOnlyIntWrapper* {{%[0-9]+}}, %struct.AddressOnlyIntWrapper* {{%[0-9]+}})
17+
// CHECK: ret void
18+
19+
// CHECK: define linkonce_odr void [[NAME]](%struct.AddressOnlyIntWrapper* {{.*}}%agg.result, %struct.AddressOnlyIntWrapper* %this, %struct.AddressOnlyIntWrapper* %rhs)
20+
21+
public func subAddressOnlyIntWrapper(_ lhs: inout AddressOnlyIntWrapper, _ rhs: AddressOnlyIntWrapper) -> AddressOnlyIntWrapper { lhs - rhs }

test/Interop/Cxx/operators/member-inline-module-interface.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
// CHECK: struct IntBox {
44
// CHECK: static func + (lhs: inout IntBox, rhs: IntBox) -> IntBox
55
// CHECK: }
6+
7+
// CHECK: struct AddressOnlyIntWrapper {
8+
// CHECK: static func - (lhs: inout AddressOnlyIntWrapper, rhs: AddressOnlyIntWrapper) -> AddressOnlyIntWrapper
9+
// CHECK: }

test/Interop/Cxx/operators/member-inline-silgen.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,27 @@
22

33
import MemberInline
44

5-
public func add(_ lhs: inout IntBox, _ rhs: IntBox) -> IntBox { lhs + rhs }
6-
5+
// CHECK-LABEL: sil @$s4main9addIntBoxySo0cD0VADz_ADtF : $@convention(thin) (@inout IntBox, IntBox) -> IntBox
76
// CHECK: bb0([[SELF:%.*]] : $*IntBox, [[RHS:%.*]] : $IntBox):
8-
97
// CHECK: [[SELFACCESS:%.*]] = begin_access [modify] [static] [[SELF]] : $*IntBox
108
// CHECK: [[OP:%.*]] = function_ref [[NAME:@(_ZN6IntBoxplES_|\?\?HIntBox@@QEAA\?AU0@U0@@Z)]] : $@convention(c) (@inout IntBox, IntBox) -> IntBox
119
// CHECK: apply [[OP]]([[SELFACCESS]], [[RHS]]) : $@convention(c) (@inout IntBox, IntBox) -> IntBox
1210
// CHECK: end_access [[SELFACCESS]] : $*IntBox
11+
// CHECK: end sil function '$s4main9addIntBoxySo0cD0VADz_ADtF'
1312

1413
// CHECK: sil [clang IntBox."+"] [[NAME]] : $@convention(c) (@inout IntBox, IntBox) -> IntBox
14+
public func addIntBox(_ lhs: inout IntBox, _ rhs: IntBox) -> IntBox { lhs + rhs }
15+
16+
// CHECK-LABEL: sil @$s4main24subAddressOnlyIntWrapperySo0cdeF0VADz_ADtF : $@convention(thin) (@inout AddressOnlyIntWrapper, @in_guaranteed AddressOnlyIntWrapper) -> @out AddressOnlyIntWrapper
17+
// CHECK: bb0([[OUT:%.*]] : $*AddressOnlyIntWrapper, [[LHS:%.*]] : $*AddressOnlyIntWrapper, [[RHS:%.*]] : $*AddressOnlyIntWrapper):
18+
// CHECK: [[RHS_TMP:%.*]] = alloc_stack $AddressOnlyIntWrapper
19+
// CHECK: copy_addr [[RHS]] to [initialization] [[RHS_TMP]] : $*AddressOnlyIntWrapper
20+
// CHECK: [[LHS_ACCESS:%.*]] = begin_access [modify] [static] [[LHS]] : $*AddressOnlyIntWrapper
21+
// CHECK: [[FN:%.*]] = function_ref [[NAME:@(_ZN21AddressOnlyIntWrappermiES_|\?\?GAddressOnlyIntWrapper@@QEAA\?AU0@U0@@Z)]] : $@convention(c) (@inout AddressOnlyIntWrapper, @in AddressOnlyIntWrapper) -> @out AddressOnlyIntWrapper
22+
// CHECK: apply [[FN]]([[OUT]], [[LHS_ACCESS]], [[RHS_TMP]]) : $@convention(c) (@inout AddressOnlyIntWrapper, @in AddressOnlyIntWrapper) -> @out AddressOnlyIntWrapper
23+
// CHECK: end_access [[LHS_ACCESS]]
24+
// CHECK: dealloc_stack [[RHS_TMP]]
25+
// CHECK: end sil function '$s4main24subAddressOnlyIntWrapperySo0cdeF0VADz_ADtF'
26+
27+
// CHECK: sil [clang AddressOnlyIntWrapper."-"] [[NAME]] : $@convention(c) (@inout AddressOnlyIntWrapper, @in AddressOnlyIntWrapper) -> @out AddressOnlyIntWrapper
28+
public func subAddressOnlyIntWrapper(_ lhs: inout AddressOnlyIntWrapper, _ rhs: AddressOnlyIntWrapper) -> AddressOnlyIntWrapper { lhs - rhs }

test/Interop/Cxx/operators/member-inline-typechecker.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import MemberInline
44

5-
var lhs = IntBox(value: 42)
6-
let rhs = IntBox(value: 23)
5+
var lhsLoadable = IntBox(value: 42)
6+
let rhsLoadable = IntBox(value: 23)
7+
let resultPlusLoadable = lhsLoadable + rhsLoadable
78

8-
let resultPlus = lhs + rhs
9+
var lhsAddressOnly = AddressOnlyIntWrapper(value: 42)
10+
var rhsAddressOnly = AddressOnlyIntWrapper(value: 23)
11+
let resultMinusAddressOnly = lhsAddressOnly - rhsAddressOnly

test/Interop/Cxx/operators/member-inline.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,12 @@ OperatorsTestSuite.test("plus") {
1919
expectEqual(65, result.value)
2020
}
2121

22+
OperatorsTestSuite.test("AddressOnlyIntWrapper.plus") {
23+
var lhs = AddressOnlyIntWrapper(value: 42)
24+
let rhs = AddressOnlyIntWrapper(value: 23)
25+
26+
let result = lhs - rhs
27+
expectEqual(19, result.value)
28+
}
29+
2230
runAllTests()

0 commit comments

Comments
 (0)