Skip to content

Commit 8f999ff

Browse files
committed
[cxx-interop] Fix a bug with explicit, nested, self-contained types (and add a test).
1 parent 4cb9dc9 commit 8f999ff

File tree

3 files changed

+40
-5
lines changed

3 files changed

+40
-5
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6782,14 +6782,14 @@ bool anySubobjectsSelfContained(const clang::CXXRecordDecl *decl) {
67826782
if (!decl->getDefinition())
67836783
return false;
67846784

6785-
if (hasCustomCopyOrMoveConstructor(decl))
6785+
if (hasCustomCopyOrMoveConstructor(decl) || hasOwnedValueAttr(decl))
67866786
return true;
67876787

67886788
auto checkType = [](clang::QualType t) {
67896789
if (auto recordType = dyn_cast<clang::RecordType>(t.getCanonicalType())) {
67906790
if (auto cxxRecord =
67916791
dyn_cast<clang::CXXRecordDecl>(recordType->getDecl())) {
6792-
return hasCustomCopyOrMoveConstructor(cxxRecord);
6792+
return anySubobjectsSelfContained(cxxRecord);
67936793
}
67946794
}
67956795

@@ -6830,9 +6830,8 @@ bool IsSafeUseOfCxxDecl::evaluate(Evaluator &evaluator,
68306830
->getParent()->getTypeForDecl()->getCanonicalTypeUnqualified();
68316831

68326832
bool parentIsSelfContained =
6833-
hasOwnedValueAttr(method->getParent()) ||
6834-
(!isForeignReferenceType(parentQualType) &&
6835-
anySubobjectsSelfContained(method->getParent()));
6833+
!isForeignReferenceType(parentQualType) &&
6834+
anySubobjectsSelfContained(method->getParent());
68366835

68376836
// If it returns a pointer or reference from an owned parent, that's a
68386837
// projection (unsafe).

test/Interop/Cxx/class/method/Inputs/unsafe-projections.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
struct NestedSelfContained;
77
struct Empty;
88
struct SelfContained;
9+
struct ExplicitSelfContained;
10+
struct NestedExplicitSelfContained;
911

1012
struct View {
1113
void *ptr;
@@ -14,6 +16,8 @@ struct View {
1416
void *empty() const;
1517
std::string name() const;
1618
NestedSelfContained nested() const;
19+
ExplicitSelfContained explicitSelfContained() const;
20+
NestedExplicitSelfContained explicitNested() const;
1721
};
1822

1923
struct SelfContained {
@@ -27,6 +31,8 @@ struct SelfContained {
2731
int value() const;
2832
View view() const;
2933
int *pointer() const;
34+
ExplicitSelfContained explicitSelfContained() const;
35+
NestedExplicitSelfContained explicitNested() const;
3036
};
3137

3238
struct NestedSelfContained {
@@ -39,6 +45,8 @@ struct NestedSelfContained {
3945
int value() const;
4046
View view() const;
4147
int *pointer() const;
48+
ExplicitSelfContained explicitSelfContained() const;
49+
NestedExplicitSelfContained explicitNested() const;
4250
};
4351

4452
struct InheritSelfContained: SelfContained {
@@ -56,6 +64,17 @@ struct __attribute__((swift_attr("import_owned"))) ExplicitSelfContained {
5664

5765
void *pointer() const;
5866
View view() const;
67+
NestedSelfContained nested() const;
68+
};
69+
70+
struct NestedExplicitSelfContained {
71+
ExplicitSelfContained m;
72+
73+
SelfContained selfContained() const;
74+
NestedSelfContained nested() const;
75+
int value() const;
76+
View view() const;
77+
int *pointer() const;
5978
};
6079

6180
struct Empty {

test/Interop/Cxx/class/method/unsafe-projections.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// CHECK: func empty() -> UnsafeMutableRawPointer!
66
// CHECK: func name() -> std{{.*}}string
77
// CHECK: func nested() -> NestedSelfContained
8+
// CHECK: func explicitSelfContained() -> ExplicitSelfContained
9+
// CHECK: func explicitNested() -> NestedExplicitSelfContained
810
// CHECK: }
911

1012
// CHECK: struct SelfContained {
@@ -15,6 +17,8 @@
1517
// CHECK: func value() -> Int32
1618
// CHECK: func __viewUnsafe() -> View
1719
// CHECK: func __pointerUnsafe() -> UnsafeMutablePointer<Int32>!
20+
// CHECK: func explicitSelfContained() -> ExplicitSelfContained
21+
// CHECK: func explicitNested() -> NestedExplicitSelfContained
1822
// CHECK: }
1923

2024
// CHECK: struct NestedSelfContained {
@@ -25,6 +29,8 @@
2529
// CHECK: func value() -> Int32
2630
// CHECK: func __viewUnsafe() -> View
2731
// CHECK: func __pointerUnsafe() -> UnsafeMutablePointer<Int32>!
32+
// CHECK: func explicitSelfContained() -> ExplicitSelfContained
33+
// CHECK: func explicitNested() -> NestedExplicitSelfContained
2834
// CHECK: }
2935

3036
// CHECK: struct InheritSelfContained {
@@ -35,11 +41,22 @@
3541
// CHECK: func value() -> Int32
3642
// CHECK: func __viewUnsafe() -> View
3743
// CHECK: func __pointerUnsafe() -> UnsafeMutablePointer<Int32>!
44+
// CHECK: func explicitSelfContained() -> ExplicitSelfContained
45+
// CHECK: func explicitNested() -> NestedExplicitSelfContained
3846
// CHECK: }
3947

4048
// CHECK: struct ExplicitSelfContained {
4149
// CHECK: func __pointerUnsafe() -> UnsafeMutableRawPointer!
4250
// CHECK: func __viewUnsafe() -> View
51+
// CHECK: func nested() -> NestedSelfContained
52+
// CHECK: }
53+
54+
// CHECK: struct NestedExplicitSelfContained {
55+
// CHECK: func selfContained() -> SelfContained
56+
// CHECK: func nested() -> NestedSelfContained
57+
// CHECK: func value() -> Int32
58+
// CHECK: func __viewUnsafe() -> View
59+
// CHECK: func __pointerUnsafe() -> UnsafeMutablePointer<Int32>!
4360
// CHECK: }
4461

4562
// CHECK: struct Empty {

0 commit comments

Comments
 (0)