Skip to content

Commit cfd5ac0

Browse files
committed
Small fixes for fragile class layout
- Narrow the fix to classes with @objc ancestry only - Pass -enable-class-resilience in class resilience executable test so that we exercise resilience there - Only enable fragile layout if the class has @objc ancestry - Add an IRGen test
1 parent 86970b0 commit cfd5ac0

File tree

4 files changed

+63
-8
lines changed

4 files changed

+63
-8
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,9 @@ class IRGenOptions {
184184
EmitStackPromotionChecks(false), PrintInlineTree(false),
185185
EmbedMode(IRGenEmbedMode::None), HasValueNamesSetting(false),
186186
ValueNames(false), EnableReflectionMetadata(true),
187-
EnableReflectionNames(true), UseIncrementalLLVMCodeGen(true),
188-
UseSwiftCall(false), GenerateProfile(false), CmdArgs(),
187+
EnableReflectionNames(true), EnableClassResilience(false),
188+
UseIncrementalLLVMCodeGen(true), UseSwiftCall(false),
189+
GenerateProfile(false), CmdArgs(),
189190
SanitizeCoverage(llvm::SanitizerCoverageOptions()) {}
190191

191192
// Get a hash of all options which influence the llvm compilation but are not

lib/IRGen/GenClass.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ namespace {
141141

142142
unsigned NumInherited = 0;
143143

144+
// If the class has @objc ancestry, we lay out resiliently-typed fields
145+
// as if they were fragile.
146+
bool CompletelyFragileLayout = false;
147+
144148
// Does the class metadata require dynamic initialization above and
145149
// beyond what the runtime can automatically achieve?
146150
//
@@ -245,6 +249,10 @@ namespace {
245249
}
246250

247251
if (superclass->hasClangNode()) {
252+
// Perform fragile layout if the class has @objc ancestry.
253+
if (!IGM.IRGen.Opts.EnableClassResilience)
254+
CompletelyFragileLayout = true;
255+
248256
// If the superclass was imported from Objective-C, its size is
249257
// not known at compile time. However, since the field offset
250258
// vector only stores offsets of stored properties defined in
@@ -329,9 +337,10 @@ namespace {
329337
// instead.
330338
Optional<CompletelyFragileScope> generateStaticLayoutRAII;
331339

332-
if (!IGM.IRGen.Opts.EnableClassResilience &&
333-
!isa<FixedTypeInfo>(eltTypeForAccess))
340+
if (CompletelyFragileLayout &&
341+
!isa<FixedTypeInfo>(eltTypeForAccess)) {
334342
generateStaticLayoutRAII.emplace(IGM);
343+
}
335344

336345
auto &eltTypeForLayout = IGM.getTypeInfo(type);
337346

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %utils/chex.py < %s > %t/objc_class_resilience.swift
3+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
4+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -I %t -emit-ir -enable-resilience %t/objc_class_resilience.swift | %FileCheck %t/objc_class_resilience.swift --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize -DINT=i%target-ptrsize
5+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -I %t -emit-ir -enable-resilience -O %t/objc_class_resilience.swift
6+
7+
// REQUIRES: objc_interop
8+
9+
import ObjectiveC
10+
import resilient_struct
11+
12+
// CHECK-32-LABEL: @"$S21objc_class_resilience23ClassWithResilientFieldC5firstSivpWvd" = hidden global i32 4
13+
// CHECK-64-LABEL: @"$S21objc_class_resilience23ClassWithResilientFieldC5firstSivpWvd" = hidden global i64 8
14+
15+
// CHECK-32-LABEL: @"$S21objc_class_resilience23ClassWithResilientFieldC6second16resilient_struct4SizeVvpWvd" = hidden global i32 8
16+
// CHECK-64-LABEL: @"$S21objc_class_resilience23ClassWithResilientFieldC6second16resilient_struct4SizeVvpWvd" = hidden global i64 16
17+
18+
// CHECK-32-LABEL: @"$S21objc_class_resilience23ClassWithResilientFieldC5thirdSivpWvd" = hidden global i32 16
19+
// CHECK-64-LABEL: @"$S21objc_class_resilience23ClassWithResilientFieldC5thirdSivpWvd" = hidden global i64 32
20+
21+
// CHECK-LABEL: @"OBJC_CLASS_$__TtC21objc_class_resilience23ClassWithResilientField" = alias
22+
23+
// CHECK-LABEL: define hidden swiftcc {{i32|i64}} @"$S21objc_class_resilience23ClassWithResilientFieldC5firstSivg"(%T21objc_class_resilience23ClassWithResilientFieldC* swiftself) {{.*}} {
24+
// CHECK: %offset = load [[INT]], [[INT]]* @"$S21objc_class_resilience23ClassWithResilientFieldC5firstSivpWvd"
25+
// CHECK: }
26+
27+
// CHECK-LABEL: define hidden swiftcc void @"$S21objc_class_resilience23ClassWithResilientFieldC6second16resilient_struct4SizeVvg"(%swift.opaque* noalias nocapture sret, %T21objc_class_resilience23ClassWithResilientFieldC* swiftself) {{.*}} {
28+
// CHECK: %offset = load [[INT]], [[INT]]* @"$S21objc_class_resilience23ClassWithResilientFieldC6second16resilient_struct4SizeVvpWvd"
29+
// CHECK: }
30+
31+
// CHECK-LABEL: define hidden swiftcc {{i32|i64}} @"$S21objc_class_resilience23ClassWithResilientFieldC5thirdSivg"(%T21objc_class_resilience23ClassWithResilientFieldC* swiftself) {{.*}} {
32+
// CHECK: %offset = load [[INT]], [[INT]]* @"$S21objc_class_resilience23ClassWithResilientFieldC5thirdSivpWvd"
33+
// CHECK: }
34+
35+
public class ClassWithResilientField : NSObject {
36+
var first: Int
37+
var second: Size
38+
var third: Int
39+
40+
init(x: Int, y: Size, z: Int) {
41+
self.first = x
42+
self.second = y
43+
self.third = z
44+
}
45+
}

test/Interpreter/class_resilience.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
// RUN: %empty-directory(%t)
22

3-
// RUN: %target-build-swift-dylib(%t/libresilient_struct.%target-dylib-extension) -Xfrontend -enable-resilience %S/../Inputs/resilient_struct.swift -emit-module -emit-module-path %t/resilient_struct.swiftmodule -module-name resilient_struct
3+
// RUN: %target-build-swift-dylib(%t/libresilient_struct.%target-dylib-extension) -Xfrontend -enable-resilience -Xfrontend -enable-class-resilience %S/../Inputs/resilient_struct.swift -emit-module -emit-module-path %t/resilient_struct.swiftmodule -module-name resilient_struct
44
// RUN: %target-codesign %t/libresilient_struct.%target-dylib-extension
55

6-
// RUN: %target-build-swift-dylib(%t/libresilient_class.%target-dylib-extension) -Xfrontend -enable-resilience %S/../Inputs/resilient_class.swift -emit-module -emit-module-path %t/resilient_class.swiftmodule -module-name resilient_class -I%t -L%t -lresilient_struct
6+
// RUN: %target-build-swift-dylib(%t/libresilient_class.%target-dylib-extension) -Xfrontend -enable-resilience -Xfrontend -enable-class-resilience %S/../Inputs/resilient_class.swift -emit-module -emit-module-path %t/resilient_class.swiftmodule -module-name resilient_class -I%t -L%t -lresilient_struct
77
// RUN: %target-codesign %t/libresilient_class.%target-dylib-extension
88

99
// RUN: %target-build-swift %s -L %t -I %t -lresilient_struct -lresilient_class -o %t/main -Xlinker -rpath -Xlinker %t
1010

1111
// RUN: %target-run %t/main %t/libresilient_struct.%target-dylib-extension %t/libresilient_class.%target-dylib-extension
1212

13-
// RUN: %target-build-swift-dylib(%t/libresilient_struct_wmo.%target-dylib-extension) -Xfrontend -enable-resilience %S/../Inputs/resilient_struct.swift -emit-module -emit-module-path %t/resilient_struct.swiftmodule -module-name resilient_struct -whole-module-optimization
13+
// RUN: %target-build-swift-dylib(%t/libresilient_struct_wmo.%target-dylib-extension) -Xfrontend -enable-resilience -Xfrontend -enable-class-resilience %S/../Inputs/resilient_struct.swift -emit-module -emit-module-path %t/resilient_struct.swiftmodule -module-name resilient_struct -whole-module-optimization
1414
// RUN: %target-codesign %t/libresilient_struct_wmo.%target-dylib-extension
1515

16-
// RUN: %target-build-swift-dylib(%t/libresilient_class_wmo.%target-dylib-extension) -Xfrontend -enable-resilience %S/../Inputs/resilient_class.swift -emit-module -emit-module-path %t/resilient_class.swiftmodule -module-name resilient_class -I%t -L%t -lresilient_struct_wmo -whole-module-optimization
16+
// RUN: %target-build-swift-dylib(%t/libresilient_class_wmo.%target-dylib-extension) -Xfrontend -enable-resilience -Xfrontend -enable-class-resilience %S/../Inputs/resilient_class.swift -emit-module -emit-module-path %t/resilient_class.swiftmodule -module-name resilient_class -I%t -L%t -lresilient_struct_wmo -whole-module-optimization
1717
// RUN: %target-codesign %t/libresilient_class_wmo.%target-dylib-extension
1818

1919
// RUN: %target-build-swift %s -L %t -I %t -lresilient_struct_wmo -lresilient_class_wmo -o %t/main -Xlinker -rpath -Xlinker %t

0 commit comments

Comments
 (0)