Skip to content

Commit 9e35a17

Browse files
committed
[cxx-interop] Members of private base classes should not be exposed
Trying to use members of C++ private base classes from Swift causes an assertion failure in ClangImporter: ``` <build dir>/swift/lib/swift/macosx/arm64/libcxxshim.h:2:66: error: cannot cast 'A' to its private base class 'B' To __swift_interopStaticCast(From from) { return static_cast<To>(from); } ^ ``` Such members should not be exposed. rdar://103871000
1 parent ac10f2a commit 9e35a17

File tree

5 files changed

+24
-0
lines changed

5 files changed

+24
-0
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5007,6 +5007,9 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
50075007
if (auto cxxRecord =
50085008
dyn_cast<clang::CXXRecordDecl>(recordDecl->getClangDecl())) {
50095009
for (auto base : cxxRecord->bases()) {
5010+
if (base.getAccessSpecifier() != clang::AccessSpecifier::AS_public)
5011+
continue;
5012+
50105013
clang::QualType baseType = base.getType();
50115014
if (auto spectType = dyn_cast<clang::TemplateSpecializationType>(baseType))
50125015
baseType = spectType->desugar();

lib/ClangImporter/ImportDecl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8442,6 +8442,9 @@ void ClangImporter::Implementation::loadAllMembersOfRecordDecl(
84428442
// If this is a C++ record, look through the base classes too.
84438443
if (auto cxxRecord = dyn_cast<clang::CXXRecordDecl>(clangRecord)) {
84448444
for (auto base : cxxRecord->bases()) {
8445+
if (base.getAccessSpecifier() != clang::AccessSpecifier::AS_public)
8446+
continue;
8447+
84458448
clang::QualType baseType = base.getType();
84468449
if (auto spectType = dyn_cast<clang::TemplateSpecializationType>(baseType))
84478450
baseType = spectType->desugar();

test/Interop/Cxx/class/inheritance/Inputs/functions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ struct DerivedFromDerived : Derived {
7777
struct __attribute__((swift_attr("import_unsafe"))) DerivedFromNonTrivial
7878
: NonTrivial {};
7979

80+
struct PrivatelyInherited : private Base {
81+
};
82+
83+
struct ProtectedInherited : protected Base {
84+
};
85+
8086
struct EmptyBaseClass {
8187
const char *inBase() const __attribute__((swift_attr("import_unsafe"))) {
8288
return "EmptyBaseClass::inBase";

test/Interop/Cxx/class/inheritance/functions-module-interface.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,11 @@
9292
// CHECK-NEXT: @discardableResult
9393
// CHECK-NEXT: func inNonTrivialWithArgs(_ a: Int32, _ b: Int32) -> UnsafePointer<CChar>?
9494
// CHECK-NEXT: }
95+
96+
// CHECK-NEXT: struct PrivatelyInherited {
97+
// CHECK-NEXT: init()
98+
// CHECK-NEXT: }
99+
100+
// CHECK-NEXT: struct ProtectedInherited {
101+
// CHECK-NEXT: init()
102+
// CHECK-NEXT: }

test/Interop/Cxx/class/inheritance/extensions-typechecker.swift renamed to test/Interop/Cxx/class/inheritance/functions-typechecker.swift

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

33
import Functions
44

5+
PrivatelyInherited().constInBase() // expected-error {{value of type 'PrivatelyInherited' has no member 'constInBase'}}
6+
ProtectedInherited().constInBase() // expected-error {{value of type 'ProtectedInherited' has no member 'constInBase'}}
7+
8+
59
extension Base {
610
public func swiftFunc() {}
711
}

0 commit comments

Comments
 (0)