Skip to content

Commit 34802ed

Browse files
committed
[cxx-interop] Fix inline operators for address-only types.
1 parent 9bbb019 commit 34802ed

File tree

7 files changed

+64
-4
lines changed

7 files changed

+64
-4
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1572,13 +1572,27 @@ class DestructureInputs {
15721572
// Add any foreign parameters that are positioned here.
15731573
maybeAddForeignParameters();
15741574

1575+
bool isCxxOperator = origType.isCXXMethod() &&
1576+
origType.getCXXMethod()->isOverloadedOperator();
1577+
15751578
// Process all the non-self parameters.
15761579
for (unsigned i = 0; i != numNonSelfParams; ++i) {
15771580
auto ty = params[i].getParameterType();
15781581
auto eltPattern = origType.getFunctionParamType(i);
15791582
auto flags = params[i].getParameterFlags();
1583+
bool forSelf = false;
1584+
1585+
// If we have an inline operator, when it was imported, it was turned
1586+
// from a method into a static function. So, we need to shift over the
1587+
// params by one and use "self" as the first param's type.
1588+
if (isCxxOperator) {
1589+
if (i == 0)
1590+
forSelf = true;
1591+
else if (i == 1)
1592+
NextOrigParamIndex--;
1593+
}
15801594

1581-
visit(flags.getValueOwnership(), /*forSelf=*/false, eltPattern, ty,
1595+
visit(flags.getValueOwnership(), forSelf, eltPattern, ty,
15821596
flags.isNoDerivative());
15831597
}
15841598

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,14 @@ struct HasDeletedOperator {
1212
void operator!=(HasDeletedOperator) const = delete;
1313
};
1414

15+
struct AddressOnlyIntWrapper {
16+
int value;
17+
AddressOnlyIntWrapper(int value) : value(value) {}
18+
AddressOnlyIntWrapper(AddressOnlyIntWrapper const &other)
19+
: value(other.value) {}
20+
AddressOnlyIntWrapper operator-(AddressOnlyIntWrapper rhs) {
21+
return AddressOnlyIntWrapper(value - rhs.value);
22+
}
23+
};
24+
1525
#endif

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

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

66
import MemberInline
77

8-
public func sub(_ lhs: inout LoadableIntWrapper, _ rhs: LoadableIntWrapper) -> LoadableIntWrapper { lhs - rhs }
9-
108
// CHECK: call [[RES:i32|i64]] [[NAME:@(_ZN18LoadableIntWrappermiES_|"\?\?GLoadableIntWrapper@@QEAA\?AU0@U0@@Z")]](%struct.LoadableIntWrapper* {{%[0-9]+}}, {{i32|\[1 x i32\]|i64|%struct.LoadableIntWrapper\* byval align 4}} {{%[0-9]+}})
9+
1110
// CHECK: define linkonce_odr [[RES]] [[NAME]](%struct.LoadableIntWrapper* %this, {{i32 %rhs.coerce|\[1 x i32\] %rhs.coerce|i64 %rhs.coerce|%struct.LoadableIntWrapper\* byval\(%struct.LoadableIntWrapper\) align 4 %rhs}})
11+
public func sub(_ lhs: inout LoadableIntWrapper, _ rhs: LoadableIntWrapper) -> LoadableIntWrapper { lhs - rhs }
12+
13+
// CHECK-LABEL: define {{.*}}void @"$s4main24subAddressOnlyIntWrapperySo0cdeF0VADz_ADtF"
14+
// CHECK: call void [[NAME:@(_ZN21AddressOnlyIntWrappermiES_|"\?\?GAddressOnlyIntWrapper@@QEAA\?AU0@U0@@Z")]](%struct.AddressOnlyIntWrapper* {{%[0-9]+}}, %struct.AddressOnlyIntWrapper* {{%[0-9]+}}, %struct.AddressOnlyIntWrapper* {{%[0-9]+}})
15+
// CHECK: ret void
16+
17+
// CHECK: define linkonce_odr void [[NAME]](%struct.AddressOnlyIntWrapper* {{.*}}%agg.result, %struct.AddressOnlyIntWrapper* %this, %struct.AddressOnlyIntWrapper* %rhs)
18+
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
@@ -6,3 +6,7 @@
66

77
// CHECK: struct HasDeletedOperator {
88
// CHECK: }
9+
10+
// CHECK: struct AddressOnlyIntWrapper {
11+
// CHECK: static func - (lhs: inout AddressOnlyIntWrapper, rhs: AddressOnlyIntWrapper) -> AddressOnlyIntWrapper
12+
// CHECK: }

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,17 @@ public func sub(_ lhs: inout LoadableIntWrapper, _ rhs: LoadableIntWrapper) -> L
1212
// CHECK: end_access [[SELFACCESS]] : $*LoadableIntWrapper
1313

1414
// CHECK: sil [clang LoadableIntWrapper."-"] [[NAME]] : $@convention(c) (@inout LoadableIntWrapper, LoadableIntWrapper) -> LoadableIntWrapper
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: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ import MemberInline
44

55
var lhs = LoadableIntWrapper(value: 42)
66
let rhs = LoadableIntWrapper(value: 23)
7+
let resultMinus = lhs - rhs
78

8-
let resultPlus = lhs - rhs
9+
var lhsAddressOnly = AddressOnlyIntWrapper(42)
10+
var rhsAddressOnly = AddressOnlyIntWrapper(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("LoadableIntWrapper.plus") {
1919
expectEqual(19, result.value)
2020
}
2121

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

0 commit comments

Comments
 (0)