Skip to content

[cxx-interop] Do not crash when calling a subscript with unnamed parameter #73337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion lib/ClangImporter/SwiftDeclSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1692,7 +1692,16 @@ SubscriptDecl *SwiftDeclSynthesizer::makeSubscript(FuncDecl *getter,
: rawElementTy;

auto &ctx = ImporterImpl.SwiftContext;
auto bodyParams = getterImpl->getParameters();

assert(getterImpl->getParameters()->size() == 1 &&
"subscript can only have 1 parameter");
auto bodyParam = ParamDecl::clone(ctx, getterImpl->getParameters()->get(0));
// If the subscript parameter is unnamed, give it a name to make sure SILGen
// creates a variable for it.
if (bodyParam->getName().empty())
bodyParam->setName(ctx.getIdentifier("__index"));

auto bodyParams = ParameterList::create(ctx, bodyParam);
DeclName name(ctx, DeclBaseName::createSubscript(), bodyParams);
auto dc = getterImpl->getDeclContext();

Expand Down
10 changes: 10 additions & 0 deletions test/Interop/Cxx/operators/Inputs/member-inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,16 @@ struct DerivedFromReadWriteIntArray : ReadWriteIntArray {};

struct DerivedFromNonTrivialArrayByVal : NonTrivialArrayByVal {};

struct SubscriptUnnamedParameter {
int operator[](int) const { return 123; }
};

struct SubscriptUnnamedParameterReadWrite {
int value = 0;
const int &operator[](int) const { return value; }
int &operator[](int) { return value; }
};

struct Iterator {
private:
int value = 123;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,13 @@
// CHECK: mutating func __operatorSubscriptConst(_ x: Int32) -> NonTrivial
// CHECK: }

// CHECK: struct SubscriptUnnamedParameter {
// CHECK: subscript(__index: Int32) -> Int32 { get }
// CHECK: }
// CHECK: struct SubscriptUnnamedParameterReadWrite {
// CHECK: subscript(__index: Int32) -> Int32
// CHECK: }

// CHECK: struct Iterator {
// CHECK: var pointee: Int32 { mutating get set }
// CHECK: @available(*, unavailable, message: "use .pointee property")
Expand Down
9 changes: 9 additions & 0 deletions test/Interop/Cxx/operators/member-inline-silgen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,15 @@ public func index(_ arr: inout ConstPtrByVal, _ arg: Int32, _ val: Int32) -> Int
// CHECK: end_access [[SELFACCESS]] : $*ConstPtrByVal
// CHECK: } // end sil function '$sSo13ConstPtrByValVySPys5Int32VGSgADcig

public func subscriptUnnamed(_ unnamed: SubscriptUnnamedParameter, _ arg: Int32) -> Int32 { unnamed[arg] }
// CHECK: sil shared [transparent] @$sSo25SubscriptUnnamedParameterVys5Int32VADcig : $@convention(method) (Int32, SubscriptUnnamedParameter) -> Int32 {
// CHECK: bb0([[INDEX:%.*]] : $Int32, [[SELF:%.*]] : $SubscriptUnnamedParameter):
// CHECK: [[SELFACCESS:%.*]] = alloc_stack $SubscriptUnnamedParameter
// CHECK: [[OP:%.*]] = function_ref [[OPERATORNAME:@(_ZNK25SubscriptUnnamedParameterixEi|\?\?ASubscriptUnnamedParameter@@QEBAHH@Z)]] : $@convention(cxx_method) (Int32, @in_guaranteed SubscriptUnnamedParameter) -> Int32
// CHECK: [[PTR:%.*]] = apply [[OP]]([[INDEX]], [[SELFACCESS]]) : $@convention(cxx_method) (Int32, @in_guaranteed SubscriptUnnamedParameter) -> Int32
// CHECK: dealloc_stack [[SELFACCESS]]
// CHECK: } // end sil function '$sSo25SubscriptUnnamedParameterVys5Int32VADcig'

// CHECK: sil [clang ReadOnlyIntArray.__operatorSubscriptConst] [[READCLASSNAME]] : $@convention(cxx_method) (Int32, @in_guaranteed ReadOnlyIntArray) -> UnsafePointer<Int32>
// CHECK: sil [clang ReadWriteIntArray.__operatorSubscript] [[READWRITECLASSNAME]] : $@convention(cxx_method) (Int32, @inout ReadWriteIntArray) -> UnsafeMutablePointer<Int32>
// CHECK: sil [clang NonTrivialIntArrayByVal.__operatorSubscriptConst] [[READWRITECLASSNAMEBYVAL]] : $@convention(cxx_method) (Int32, @in_guaranteed NonTrivialIntArrayByVal) -> Int32
Expand Down
16 changes: 16 additions & 0 deletions test/Interop/Cxx/operators/member-inline.swift
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,22 @@ OperatorsTestSuite.test("SubscriptSetterConst") {
setterConst[0] = 10
}

OperatorsTestSuite.test("SubscriptUnnamedParameter") {
let unnamed = SubscriptUnnamedParameter()
expectEqual(123, unnamed[0])
expectEqual(123, unnamed[321])
}

OperatorsTestSuite.test("SubscriptUnnamedParameterReadWrite") {
var unnamed = SubscriptUnnamedParameterReadWrite()
expectEqual(0, unnamed[0])
expectEqual(0, unnamed[321])

unnamed[456] = 456
expectEqual(456, unnamed[0])
expectEqual(456, unnamed[321])
}

OperatorsTestSuite.test("DerivedFromConstIteratorPrivatelyWithUsingDecl.pointee") {
let stars = DerivedFromConstIteratorPrivatelyWithUsingDecl()
let res = stars.pointee
Expand Down