Skip to content

Commit 6e878df

Browse files
authored
Merge pull request #65740 from apple/egorzhdan/cxx-computed-property
[cxx-interop] Do not mix up computed properties from different records
2 parents ff52726 + 42b3973 commit 6e878df

File tree

3 files changed

+48
-9
lines changed

3 files changed

+48
-9
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2437,7 +2437,7 @@ namespace {
24372437
structResult->setIsCxxNonTrivial(
24382438
isNonTrivialForPurposeOfCalls(cxxRecordDecl));
24392439

2440-
for (auto &getterAndSetter : Impl.GetterSetterMap) {
2440+
for (auto &getterAndSetter : Impl.GetterSetterMap[result]) {
24412441
auto getter = getterAndSetter.second.first;
24422442
auto setter = getterAndSetter.second.second;
24432443
// We cannot make a computed property without a getter.
@@ -3521,13 +3521,17 @@ namespace {
35213521

35223522
if (Impl.SwiftContext.LangOpts.CxxInteropGettersSettersAsProperties ||
35233523
hasComputedPropertyAttr(decl)) {
3524-
CXXMethodBridging bridgingInfo(decl);
3525-
if (bridgingInfo.classify() == CXXMethodBridging::Kind::getter) {
3526-
auto name = bridgingInfo.getClangName().drop_front(3);
3527-
Impl.GetterSetterMap[name].first = static_cast<FuncDecl *>(method);
3528-
} else if (bridgingInfo.classify() == CXXMethodBridging::Kind::setter) {
3529-
auto name = bridgingInfo.getClangName().drop_front(3);
3530-
Impl.GetterSetterMap[name].second = static_cast<FuncDecl *>(method);
3524+
if (auto funcDecl = dyn_cast_or_null<FuncDecl>(method)) {
3525+
auto parent = funcDecl->getParent()->getSelfNominalTypeDecl();
3526+
CXXMethodBridging bridgingInfo(decl);
3527+
if (bridgingInfo.classify() == CXXMethodBridging::Kind::getter) {
3528+
auto name = bridgingInfo.getClangName().drop_front(3);
3529+
Impl.GetterSetterMap[parent][name].first = funcDecl;
3530+
} else if (bridgingInfo.classify() ==
3531+
CXXMethodBridging::Kind::setter) {
3532+
auto name = bridgingInfo.getClangName().drop_front(3);
3533+
Impl.GetterSetterMap[parent][name].second = funcDecl;
3534+
}
35313535
}
35323536
}
35333537

lib/ClangImporter/ImporterImpl.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,10 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
603603
/// Keep track of subscript declarations based on getter/setter
604604
/// pairs.
605605
llvm::DenseMap<std::pair<FuncDecl *, FuncDecl *>, SubscriptDecl *> Subscripts;
606-
llvm::DenseMap<llvm::StringRef, std::pair<FuncDecl *, FuncDecl *>>
606+
607+
llvm::DenseMap<
608+
NominalTypeDecl *,
609+
llvm::DenseMap<llvm::StringRef, std::pair<FuncDecl *, FuncDecl *>>>
607610
GetterSetterMap;
608611

609612
/// Keep track of getter/setter pairs for functions imported from C++
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
// RUN: %target-build-swift %t/test.swift -I %t/Inputs -Xfrontend -enable-experimental-cxx-interop -typecheck
4+
5+
//--- Inputs/module.modulemap
6+
module Test {
7+
header "test.h"
8+
requires cplusplus
9+
}
10+
11+
//--- Inputs/test.h
12+
13+
#define SWIFT_COMPUTED_PROPERTY \
14+
__attribute__((swift_attr("import_computed_property")))
15+
16+
struct FirstRecordWithX {
17+
int getX() const SWIFT_COMPUTED_PROPERTY { return 42; }
18+
};
19+
20+
struct SecondRecordWithXUsesFirst {
21+
int getX() const SWIFT_COMPUTED_PROPERTY { return 21; }
22+
23+
const FirstRecordWithX * getY() const { return nullptr; }
24+
};
25+
26+
//--- test.swift
27+
28+
import Test
29+
30+
func test(_ val: SecondRecordWithXUsesFirst) {
31+
let _ = val.x
32+
}

0 commit comments

Comments
 (0)