Skip to content

Commit 67e3e86

Browse files
Merge pull request #41044 from aschwaighofer/irgen_enable_testing_has_resilient_metadata
IRGen: Take enable-testing into account when computing whether a class has resilient metadata
2 parents 3e228bd + d48422f commit 67e3e86

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

lib/IRGen/ClassMetadataVisitor.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,17 @@ template <class Impl> class ClassMetadataVisitor
116116
if (superclassDecl->hasClangNode()) {
117117
// Nothing to do; Objective-C classes do not add new members to
118118
// Swift class metadata.
119-
} else if (IGM.hasResilientMetadata(superclassDecl, ResilienceExpansion::Maximal)) {
119+
120+
// Super class metadata is resilient if
121+
// the superclass is resilient when viewed from the currrent module.
122+
// But not if the current class is defined in an external module and
123+
// not publically accessible (e.g private or internal). This would
124+
// normally not happen except if we compile theClass's module with
125+
// enable-testing.
126+
} else if (IGM.hasResilientMetadata(superclassDecl, ResilienceExpansion::Maximal) &&
127+
(theClass->getModuleContext() == IGM.getSwiftModule() ||
128+
theClass->getFormalAccessScope(/*useDC=*/nullptr,
129+
/*treatUsableFromInlineAsPublic=*/true).isPublic())) {
120130
// Runtime metadata instantiation will initialize our field offset
121131
// vector and vtable entries.
122132
//
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
open class Base {
2+
var x = 1
3+
}
4+
5+
internal class SubClass : Base {
6+
var y = 2
7+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -enable-testing -enable-library-evolution -module-name=resilient %S/Inputs/resilient-class.swift -emit-module -emit-module-path %t/resilient.swiftmodule
3+
// RUN: %target-swift-frontend -I %t -emit-ir %s | %FileCheck %s
4+
5+
// Check that linking succeeds.
6+
// RUN: %empty-directory(%t)
7+
// RUN: %target-build-swift-dylib(%t/%target-library-name(resilient)) %S/Inputs/resilient-class.swift -module-name resilient -emit-module -emit-module-path %t/resilient.swiftmodule -enable-library-evolution -enable-testing
8+
// RUN: %target-build-swift -I %t -L %t -lresilient %s -o %t/main %target-rpath(%t)
9+
// RUN: %target-build-swift -O -I %t -L %t -lresilient %s -o %t/main %target-rpath(%t)
10+
11+
@testable import resilient
12+
13+
// Don't access via the class offset global. Use a fragile access pattern instead.
14+
15+
// CHECK-NOT: s9resilient8SubClassCMo
16+
17+
public func testCase() {
18+
let t = SubClass()
19+
print(t.y)
20+
}

0 commit comments

Comments
 (0)