Skip to content

Commit 428892d

Browse files
authored
Merge pull request #41536 from Huddie/fix-cxx-mutable-lookup-failure
[cxx interop] Fix issue where const overloaded disambiguated methods were not in the lookup table
2 parents 4c098df + 4d2a40b commit 428892d

File tree

4 files changed

+38
-22
lines changed

4 files changed

+38
-22
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3444,11 +3444,12 @@ namespace {
34443444
// that differ this way so we can disambiguate later
34453445
for (auto m : decl->decls()) {
34463446
if (auto method = dyn_cast<clang::CXXMethodDecl>(m)) {
3447-
if(method->getDeclName().isIdentifier()) {
3448-
if(Impl.cxxMethods.find(method->getName()) == Impl.cxxMethods.end()) {
3447+
if (method->getDeclName().isIdentifier()) {
3448+
if (Impl.cxxMethods.find(method->getName()) ==
3449+
Impl.cxxMethods.end()) {
34493450
Impl.cxxMethods[method->getName()] = {};
34503451
}
3451-
if(method->isConst()) {
3452+
if (method->isConst()) {
34523453
// Add to const set
34533454
Impl.cxxMethods[method->getName()].first.insert(method);
34543455
} else {
@@ -3478,8 +3479,8 @@ namespace {
34783479

34793480
if (auto field = dyn_cast<clang::FieldDecl>(nd)) {
34803481
// Non-nullable pointers can't be zero-initialized.
3481-
if (auto nullability = field->getType()
3482-
->getNullability(Impl.getClangASTContext())) {
3482+
if (auto nullability =
3483+
field->getType()->getNullability(Impl.getClangASTContext())) {
34833484
if (*nullability == clang::NullabilityKind::NonNull)
34843485
hasZeroInitializableStorage = false;
34853486
}
@@ -3522,6 +3523,18 @@ namespace {
35223523
}
35233524

35243525
if (auto MD = dyn_cast<FuncDecl>(member)) {
3526+
3527+
// When 2 CXXMethods diff by "constness" alone we differentiate them
3528+
// by changing the name of one. That changed method needs to be added
3529+
// to the lookup table since it cannot be found lazily.
3530+
if (auto cxxMethod = dyn_cast<clang::CXXMethodDecl>(m)) {
3531+
if (cxxMethod->getDeclName().isIdentifier()) {
3532+
auto &mutableFuncPtrs = Impl.cxxMethods[cxxMethod->getName()].second;
3533+
if(mutableFuncPtrs.contains(cxxMethod)) {
3534+
result->addMemberToLookupTable(member);
3535+
}
3536+
}
3537+
}
35253538
methods.push_back(MD);
35263539
continue;
35273540
}
@@ -3602,10 +3615,10 @@ namespace {
36023615
//
36033616
// If we can completely represent the struct in SIL, leave the body
36043617
// implicit, otherwise synthesize one to call property setters.
3605-
auto valueCtor = createValueConstructor(
3606-
Impl, result, members,
3607-
/*want param names*/true,
3608-
/*want body*/hasUnreferenceableStorage);
3618+
auto valueCtor =
3619+
createValueConstructor(Impl, result, members,
3620+
/*want param names*/ true,
3621+
/*want body*/ hasUnreferenceableStorage);
36093622
if (!hasUnreferenceableStorage)
36103623
valueCtor->setIsMemberwiseInitializer();
36113624

@@ -3636,8 +3649,8 @@ namespace {
36363649
continue;
36373650

36383651
auto getterAndSetter = subscriptInfo.second;
3639-
auto subscript = makeSubscript(getterAndSetter.first,
3640-
getterAndSetter.second);
3652+
auto subscript =
3653+
makeSubscript(getterAndSetter.first, getterAndSetter.second);
36413654
// Also add subscripts directly because they won't be found from the
36423655
// clang decl.
36433656
result->addMember(subscript);

test/Interop/Cxx/class/method/Inputs/ambiguous_methods.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@
33

44
struct HasAmbiguousMethods {
55

6-
// No input
7-
void ping() { ++mutableMethodsCalledCount; }
8-
void ping() const {}
9-
106
// One input (const first)
117
int increment(int a) const {
128
return a + 1;

test/Interop/Cxx/class/method/ambiguous-methods-module-interface.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
// RUN: %target-swift-ide-test -print-module -module-to-print=AmbiguousMethods -I %S/Inputs -source-filename=x -enable-cxx-interop | %FileCheck %s
22

3-
// CHECK: mutating func pingMutating()
4-
// CHECK: func ping()
5-
63
// CHECK: func increment(_ a: Int32) -> Int32
74
// CHECK: mutating func incrementMutating(_ a: Int32) -> Int32
85

test/Interop/Cxx/class/method/ambiguous-methods.swift

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,30 @@ import AmbiguousMethods
88

99
var CxxAmbiguousMethodTestSuite = TestSuite("CxxAmbiguousMethods")
1010

11-
CxxAmbiguousMethodTestSuite.test("numberOfMutableMethodsCalled: () -> Int") {
11+
// It's important to check that both calling the const version first
12+
// and the mutable version first pass. This helps confirm that the lookup
13+
// table is being properly seeded.
14+
CxxAmbiguousMethodTestSuite.test("[Const First] numberOfMutableMethodsCalled: () -> Int") {
1215
var instance = HasAmbiguousMethods()
1316

1417
// Sanity check. Make sure we start at 0
18+
// and that calling numberOfMutableMethodsCalled doesn't change
19+
// the count
1520
expectEqual(0, instance.numberOfMutableMethodsCalled())
16-
17-
// Make sure calling numberOfMutableMethodsCalled above didn't
18-
// change the count
1921
expectEqual(0, instance.numberOfMutableMethodsCalled())
2022

2123
// Check that mutable version _does_ change the mutable call count
24+
expectEqual(0, instance.numberOfMutableMethodsCalled())
2225
expectEqual(1, instance.numberOfMutableMethodsCalledMutating())
26+
}
2327

28+
CxxAmbiguousMethodTestSuite.test("[Mutable First] numberOfMutableMethodsCalled: () -> Int") {
29+
var instance = HasAmbiguousMethods()
30+
31+
// Call mutable first
32+
expectEqual(1, instance.numberOfMutableMethodsCalledMutating())
2433
expectEqual(1, instance.numberOfMutableMethodsCalled())
34+
2535
}
2636

2737
CxxAmbiguousMethodTestSuite.test("Basic Increment: (Int) -> Int") {

0 commit comments

Comments
 (0)