Skip to content

Commit c88e65b

Browse files
authored
Merge pull request #73337 from apple/egorzhdan/unnamed-subscript-param
[cxx-interop] Do not crash when calling a subscript with unnamed parameter
2 parents c10f5eb + ae27e88 commit c88e65b

File tree

5 files changed

+52
-1
lines changed

5 files changed

+52
-1
lines changed

lib/ClangImporter/SwiftDeclSynthesizer.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1692,7 +1692,16 @@ SubscriptDecl *SwiftDeclSynthesizer::makeSubscript(FuncDecl *getter,
16921692
: rawElementTy;
16931693

16941694
auto &ctx = ImporterImpl.SwiftContext;
1695-
auto bodyParams = getterImpl->getParameters();
1695+
1696+
assert(getterImpl->getParameters()->size() == 1 &&
1697+
"subscript can only have 1 parameter");
1698+
auto bodyParam = ParamDecl::clone(ctx, getterImpl->getParameters()->get(0));
1699+
// If the subscript parameter is unnamed, give it a name to make sure SILGen
1700+
// creates a variable for it.
1701+
if (bodyParam->getName().empty())
1702+
bodyParam->setName(ctx.getIdentifier("__index"));
1703+
1704+
auto bodyParams = ParameterList::create(ctx, bodyParam);
16961705
DeclName name(ctx, DeclBaseName::createSubscript(), bodyParams);
16971706
auto dc = getterImpl->getDeclContext();
16981707

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,16 @@ struct DerivedFromReadWriteIntArray : ReadWriteIntArray {};
386386

387387
struct DerivedFromNonTrivialArrayByVal : NonTrivialArrayByVal {};
388388

389+
struct SubscriptUnnamedParameter {
390+
int operator[](int) const { return 123; }
391+
};
392+
393+
struct SubscriptUnnamedParameterReadWrite {
394+
int value = 0;
395+
const int &operator[](int) const { return value; }
396+
int &operator[](int) { return value; }
397+
};
398+
389399
struct Iterator {
390400
private:
391401
int value = 123;

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,13 @@
211211
// CHECK: mutating func __operatorSubscriptConst(_ x: Int32) -> NonTrivial
212212
// CHECK: }
213213

214+
// CHECK: struct SubscriptUnnamedParameter {
215+
// CHECK: subscript(__index: Int32) -> Int32 { get }
216+
// CHECK: }
217+
// CHECK: struct SubscriptUnnamedParameterReadWrite {
218+
// CHECK: subscript(__index: Int32) -> Int32
219+
// CHECK: }
220+
214221
// CHECK: struct Iterator {
215222
// CHECK: var pointee: Int32 { mutating get set }
216223
// CHECK: @available(*, unavailable, message: "use .pointee property")

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,15 @@ public func index(_ arr: inout ConstPtrByVal, _ arg: Int32, _ val: Int32) -> Int
171171
// CHECK: end_access [[SELFACCESS]] : $*ConstPtrByVal
172172
// CHECK: } // end sil function '$sSo13ConstPtrByValVySPys5Int32VGSgADcig
173173

174+
public func subscriptUnnamed(_ unnamed: SubscriptUnnamedParameter, _ arg: Int32) -> Int32 { unnamed[arg] }
175+
// CHECK: sil shared [transparent] @$sSo25SubscriptUnnamedParameterVys5Int32VADcig : $@convention(method) (Int32, SubscriptUnnamedParameter) -> Int32 {
176+
// CHECK: bb0([[INDEX:%.*]] : $Int32, [[SELF:%.*]] : $SubscriptUnnamedParameter):
177+
// CHECK: [[SELFACCESS:%.*]] = alloc_stack $SubscriptUnnamedParameter
178+
// CHECK: [[OP:%.*]] = function_ref [[OPERATORNAME:@(_ZNK25SubscriptUnnamedParameterixEi|\?\?ASubscriptUnnamedParameter@@QEBAHH@Z)]] : $@convention(cxx_method) (Int32, @in_guaranteed SubscriptUnnamedParameter) -> Int32
179+
// CHECK: [[PTR:%.*]] = apply [[OP]]([[INDEX]], [[SELFACCESS]]) : $@convention(cxx_method) (Int32, @in_guaranteed SubscriptUnnamedParameter) -> Int32
180+
// CHECK: dealloc_stack [[SELFACCESS]]
181+
// CHECK: } // end sil function '$sSo25SubscriptUnnamedParameterVys5Int32VADcig'
182+
174183
// CHECK: sil [clang ReadOnlyIntArray.__operatorSubscriptConst] [[READCLASSNAME]] : $@convention(cxx_method) (Int32, @in_guaranteed ReadOnlyIntArray) -> UnsafePointer<Int32>
175184
// CHECK: sil [clang ReadWriteIntArray.__operatorSubscript] [[READWRITECLASSNAME]] : $@convention(cxx_method) (Int32, @inout ReadWriteIntArray) -> UnsafeMutablePointer<Int32>
176185
// CHECK: sil [clang NonTrivialIntArrayByVal.__operatorSubscriptConst] [[READWRITECLASSNAMEBYVAL]] : $@convention(cxx_method) (Int32, @in_guaranteed NonTrivialIntArrayByVal) -> Int32

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,22 @@ OperatorsTestSuite.test("SubscriptSetterConst") {
394394
setterConst[0] = 10
395395
}
396396

397+
OperatorsTestSuite.test("SubscriptUnnamedParameter") {
398+
let unnamed = SubscriptUnnamedParameter()
399+
expectEqual(123, unnamed[0])
400+
expectEqual(123, unnamed[321])
401+
}
402+
403+
OperatorsTestSuite.test("SubscriptUnnamedParameterReadWrite") {
404+
var unnamed = SubscriptUnnamedParameterReadWrite()
405+
expectEqual(0, unnamed[0])
406+
expectEqual(0, unnamed[321])
407+
408+
unnamed[456] = 456
409+
expectEqual(456, unnamed[0])
410+
expectEqual(456, unnamed[321])
411+
}
412+
397413
OperatorsTestSuite.test("DerivedFromConstIteratorPrivatelyWithUsingDecl.pointee") {
398414
let stars = DerivedFromConstIteratorPrivatelyWithUsingDecl()
399415
let res = stars.pointee

0 commit comments

Comments
 (0)