Skip to content

Commit 80855c8

Browse files
committed
Fix global accessor and class linker errors.
Add global accessors to symbol list if VarDecl is fragile, i.e. is non-resilient or its defining module allows non-resilient access. Don't set the class decl to hidden if it's in a package resilience domain; even though its defining module is built resilently, the class symbol should be visible across modules if they are in the same package with resilience-bypass optimization. In such case, treat its SubclassScope to Internal. Resolves rdar://127321129
1 parent 295c845 commit 80855c8

File tree

7 files changed

+188
-14
lines changed

7 files changed

+188
-14
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6015,6 +6015,11 @@ class AbstractStorageDecl : public ValueDecl {
60156015
/// property from the given module?
60166016
bool isResilient(ModuleDecl *M, ResilienceExpansion expansion) const;
60176017

6018+
/// True if the decl is non-resilient, or its defining module allows
6019+
/// non-resilient access so its consuming modules within the same
6020+
/// package can have visibility into this decl.
6021+
bool isFragile() const;
6022+
60186023
/// True if the storage can be referenced by a keypath directly.
60196024
/// Otherwise, its override must be referenced.
60206025
bool isValidKeyPathComponent() const;

lib/AST/Decl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3032,6 +3032,10 @@ bool Decl::isOutermostPrivateOrFilePrivateScope() const {
30323032
!isInPrivateOrLocalContext(this);
30333033
}
30343034

3035+
bool AbstractStorageDecl::isFragile() const {
3036+
return !isResilient() || getModuleContext()->allowNonResilientAccess();
3037+
}
3038+
30353039
bool AbstractStorageDecl::isResilient() const {
30363040
// Check for an explicit @_fixed_layout attribute.
30373041
if (getAttrs().hasAttribute<FixedLayoutAttr>())

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -460,12 +460,8 @@ static LinkageLimit getLinkageLimit(SILDeclRef constant) {
460460
case Kind::EnumElement:
461461
return Limit::OnDemand;
462462

463-
case Kind::GlobalAccessor: {
464-
auto varDecl = cast<VarDecl>(d);
465-
return varDecl->isResilient() &&
466-
!varDecl->getModuleContext()->allowNonResilientAccess() ?
467-
Limit::NeverPublic : Limit::None;
468-
}
463+
case Kind::GlobalAccessor:
464+
return !cast<VarDecl>(d)->isFragile() ? Limit::NeverPublic : Limit::None;
469465

470466
case Kind::DefaultArgGenerator:
471467
// If the default argument is to be serialized, only use non-ABI public
@@ -511,7 +507,8 @@ static LinkageLimit getLinkageLimit(SILDeclRef constant) {
511507
return Limit::AlwaysEmitIntoClient;
512508

513509
// FIXME: This should always be true.
514-
if (d->getModuleContext()->isResilient())
510+
if (d->getModuleContext()->isResilient() &&
511+
!d->getModuleContext()->allowNonResilientAccess())
515512
return Limit::NeverPublic;
516513

517514
break;
@@ -1532,7 +1529,8 @@ SubclassScope SILDeclRef::getSubclassScope() const {
15321529
// FIXME: This is too narrow. Any class with resilient metadata should
15331530
// probably have this, at least for method overrides that don't add new
15341531
// vtable entries.
1535-
bool isResilientClass = classType->isResilient();
1532+
bool isResilientClass = classType->isResilient() &&
1533+
!classType->getModuleContext()->allowNonResilientAccess();
15361534

15371535
if (auto *CD = dyn_cast<ConstructorDecl>(decl)) {
15381536
if (isResilientClass)

lib/SIL/IR/SILSymbolVisitor.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ class SILSymbolVisitorImpl : public ASTVisitor<SILSymbolVisitorImpl> {
579579

580580
void visitVarDecl(VarDecl *VD) {
581581
// Variables inside non-resilient modules have some additional symbols.
582-
if (!VD->isResilient()) {
582+
if (VD->isFragile()) {
583583
// Non-global variables might have an explicit initializer symbol in
584584
// non-resilient modules.
585585
if (VD->getAttrs().hasAttribute<HasInitialValueAttr>() &&
@@ -589,25 +589,21 @@ class SILSymbolVisitorImpl : public ASTVisitor<SILSymbolVisitorImpl> {
589589
// Stored property initializers for public properties are public.
590590
addFunction(declRef);
591591
}
592-
593592
// Statically/globally stored variables have some special handling.
594593
if (VD->hasStorage() && isGlobalOrStaticVar(VD)) {
595594
if (!shouldSkipVisit(getDeclLinkage(VD))) {
596595
Visitor.addGlobalVar(VD);
597596
}
598-
599597
if (VD->isLazilyInitializedGlobal())
600598
addFunction(SILDeclRef(VD, SILDeclRef::Kind::GlobalAccessor));
601599
}
602-
603600
// Wrapped non-static member properties may have a backing initializer.
604601
auto initInfo = VD->getPropertyWrapperInitializerInfo();
605602
if (initInfo.hasInitFromWrappedValue() && !VD->isStatic()) {
606603
addFunction(SILDeclRef(
607604
VD, SILDeclRef::Kind::PropertyWrapperBackingInitializer));
608605
}
609606
}
610-
611607
visitAbstractStorageDecl(VD);
612608
}
613609

lib/Sema/TypeCheckStorage.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2537,7 +2537,7 @@ RequiresOpaqueAccessorsRequest::evaluate(Evaluator &evaluator,
25372537

25382538
} else if (dc->isModuleScopeContext()) {
25392539
// Fixed-layout global variables don't require opaque accessors.
2540-
if (!var->isResilient() && !var->shouldUseNativeDynamicDispatch())
2540+
if (var->isFragile() && !var->shouldUseNativeDynamicDispatch())
25412541
return false;
25422542

25432543
// Stored properties imported from Clang don't require opaque accessors.
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-build-swift %t/Core.swift \
5+
// RUN: -module-name=Core -package-name Pkg \
6+
// RUN: -Xfrontend -experimental-allow-non-resilient-access \
7+
// RUN: -enable-library-evolution -O -wmo \
8+
// RUN: -emit-ir -o %t/Core.ir \
9+
// RUN: -emit-tbd -emit-tbd-path %t/libCore.tbd \
10+
// RUN: -Xfrontend -tbd-install_name=libCore.dylib -Xfrontend -validate-tbd-against-ir=all
11+
12+
// RUN: %FileCheck %s --check-prefix=CHECK-IR < %t/Core.ir
13+
// RUN: %FileCheck %s --check-prefix=CHECK-TBD < %t/libCore.tbd
14+
15+
//--- Core.swift
16+
17+
final public class Pub {}
18+
19+
package class Foo {
20+
package var myFoo: Pub?
21+
}
22+
23+
final package class Bar {
24+
package var myBar: Pub?
25+
}
26+
27+
// key path getter for Core.Foo.myFoo
28+
// CHECK-IR-DAG: define linkonce_odr hidden swiftcc void @"$s4Core3FooC02myB0AA3PubCSgvpACTK"
29+
30+
// key path setter for Core.Foo.myFoo
31+
// CHECK-IR-DAG: define linkonce_odr hidden swiftcc void @"$s4Core3FooC02myB0AA3PubCSgvpACTk"
32+
33+
// variable initialization expression of Core.Foo.myFoo
34+
// CHECK-IR-DAG: define swiftcc {{i32|i64}} @"$s4Core3FooC02myB0AA3PubCSgvpfi"() #0 {
35+
36+
// Core.Foo.myFoo.getter
37+
// CHECK-IR-DAG: define swiftcc {{i32|i64}} @"$s4Core3FooC02myB0AA3PubCSgvg"(ptr swiftself %0)
38+
39+
// merged Core.Foo.myFoo.getter
40+
// CHECK-IR-DAG: define internal swiftcc {{i32|i64}} @"$s4Core3FooC02myB0AA3PubCSgvgTm"(ptr swiftself %0)
41+
42+
// Core.Foo.myFoo.setter
43+
// CHECK-IR-DAG: define swiftcc void @"$s4Core3FooC02myB0AA3PubCSgvs"({{i32|i64}} %0, ptr swiftself %1) #1 {
44+
45+
// merged Core.Foo.myFoo.setter
46+
// CHECK-IR-DAG: define internal swiftcc void @"$s4Core3FooC02myB0AA3PubCSgvsTm"({{i32|i64}} %0, ptr swiftself %1)
47+
48+
// Core.Foo.myFoo.modify
49+
// CHECK-IR-DAG: define swiftcc { ptr, ptr } @"$s4Core3FooC02myB0AA3PubCSgvM"
50+
51+
// Core.Foo.myFoo.modify
52+
// CHECK-IR-DAG: define internal swiftcc void @"$s4Core3FooC02myB0AA3PubCSgvM.resume.0"
53+
54+
// type metadata accessor for Core.Foo
55+
// CHECK-IR-DAG: define swiftcc %swift.metadata_response @"$s4Core3FooCMa"
56+
57+
// method lookup function for Core.Foo
58+
// CHECK-IR-DAG: define swiftcc ptr @"$s4Core3FooCMu"(ptr %0, ptr %1)
59+
60+
// dispatch thunk of Core.Foo.myFoo.getter
61+
// CHECK-IR-DAG: define swiftcc {{i32|i64}} @"$s4Core3FooC02myB0AA3PubCSgvgTj"(ptr swiftself %0)
62+
63+
// dispatch thunk of Core.Foo.myFoo.setter
64+
// CHECK-IR-DAG: define swiftcc void @"$s4Core3FooC02myB0AA3PubCSgvsTj"({{i32|i64}} %0, ptr swiftself %1)
65+
66+
// dispatch thunk of Core.Foo.myFoo.modify
67+
// CHECK-IR-DAG: define swiftcc { ptr, ptr } @"$s4Core3FooC02myB0AA3PubCSgvMTj"
68+
69+
// Core.Foo.deinit
70+
// CHECK-IR-DAG: define swiftcc ptr @"$s4Core3FooCfd"(ptr readonly returned swiftself %0)
71+
72+
// Core.Foo.__deallocating_deinit
73+
// CHECK-IR-DAG: define swiftcc void @"$s4Core3FooCfD"(ptr swiftself %0)
74+
75+
76+
// Core.Bar.myBar
77+
// CHECK-IR-DAG: define swiftcc {{i32|i64}} @"$s4Core3BarC02myB0AA3PubCSgvpfi"()
78+
// CHECK-IR-DAG: define swiftcc {{i32|i64}} @"$s4Core3BarC02myB0AA3PubCSgvg"(ptr swiftself %0)
79+
// CHECK-IR-DAG: define swiftcc void @"$s4Core3BarC02myB0AA3PubCSgvs"({{i32|i64}} %0, ptr swiftself %1)
80+
// CHECK-IR-DAG: define swiftcc { ptr, ptr } @"$s4Core3BarC02myB0AA3PubCSgvM"
81+
// CHECK-IR-DAG: define internal swiftcc void @"$s4Core3BarC02myB0AA3PubCSgvM.resume.0"
82+
83+
// Core.Bar
84+
// type metadata accessor for Core.Bar
85+
// CHECK-IR-DAG: define swiftcc %swift.metadata_response @"$s4Core3BarCMa"({{i32|i64}} %0)
86+
87+
// method lookup function for Core.Bar
88+
// CHECK-IR-DAG: define swiftcc ptr @"$s4Core3BarCMu"(ptr %0, ptr %1)
89+
90+
// CHECK-IR-DAG: define swiftcc ptr @"$s4Core3BarCfd"(ptr readonly returned swiftself %0)
91+
// CHECK-IR-DAG: define swiftcc void @"$s4Core3BarCfD"(ptr swiftself %0)
92+
93+
// Core.Pub
94+
// type metadata accessor for Core.Pub
95+
// CHECK-IR-DAG: define swiftcc %swift.metadata_response @"$s4Core3PubCMa"({{i32|i64}} %0)
96+
97+
// method lookup function for Core.Pub
98+
// CHECK-IR-DAG: define swiftcc ptr @"$s4Core3PubCMu"(ptr %0, ptr %1)
99+
100+
// CHECK-IR-DAG: define swiftcc ptr @"$s4Core3PubCfd"(ptr readnone returned swiftself %0)
101+
// CHECK-IR-DAG: define swiftcc void @"$s4Core3PubCfD"(ptr swiftself %0)
102+
103+
104+
// property descriptor for Core.Foo.myFoo
105+
// CHECK-TBD-DAG: s4Core3FooC02myB0AA3PubCSgvpMV
106+
// method descriptor for Core.Foo.myFoo.getter
107+
// CHECK-TBD-DAG: s4Core3FooC02myB0AA3PubCSgvgTq
108+
// method descriptor for Core.Foo.myFoo.setter
109+
// CHECK-TBD-DAG: s4Core3FooC02myB0AA3PubCSgvsTq
110+
// method descriptor for Core.Foo.myFoo.modify
111+
// CHECK-TBD-DAG: s4Core3FooC02myB0AA3PubCSgvMTq
112+
// dispatch thunk of Core.Foo.myFoo.getter
113+
// CHECK-TBD-DAG: s4Core3FooC02myB0AA3PubCSgvgTj
114+
// dispatch thunk of Core.Foo.myFoo.setter
115+
// CHECK-TBD-DAG: s4Core3FooC02myB0AA3PubCSgvsTj
116+
// dispatch thunk of Core.Foo.myFoo.modify
117+
// CHECK-TBD-DAG: s4Core3FooC02myB0AA3PubCSgvMTj
118+
// type metadata accessor for Core.Foo
119+
// CHECK-TBD-DAG: s4Core3FooCMa
120+
// method lookup function for Core.Foo
121+
// CHECK-TBD-DAG: s4Core3FooCMu
122+
// nominal type descriptor for Core.Foo
123+
// CHECK-TBD-DAG: s4Core3FooCMn
124+
// class metadata base offset for Core.Foo
125+
// CHECK-TBD-DAG: s4Core3FooCMo
126+
127+
// CHECK-TBD-DAG: s4Core3FooC02myB0AA3PubCSgvpfi
128+
// CHECK-TBD-DAG: s4Core3FooC02myB0AA3PubCSgvg
129+
// CHECK-TBD-DAG: s4Core3FooC02myB0AA3PubCSgvs
130+
// CHECK-TBD-DAG: s4Core3FooCfd
131+
// CHECK-TBD-DAG: s4Core3FooCfD
132+
133+
// CHECK-TBD-DAG: s4Core3BarC02myB0AA3PubCSgvpMV
134+
// CHECK-TBD-DAG: s4Core3BarC02myB0AA3PubCSgvpfi
135+
// CHECK-TBD-DAG: s4Core3BarC02myB0AA3PubCSgvg
136+
// CHECK-TBD-DAG: s4Core3BarC02myB0AA3PubCSgvs
137+
// CHECK-TBD-DAG: s4Core3BarC02myB0AA3PubCSgvM
138+
// CHECK-TBD-DAG: s4Core3BarCMa
139+
// CHECK-TBD-DAG: s4Core3BarCMu
140+
// CHECK-TBD-DAG: s4Core3BarCMn
141+
// CHECK-TBD-DAG: s4Core3BarCMo
142+
// CHECK-TBD-DAG: s4Core3BarCfd
143+
// CHECK-TBD-DAG: s4Core3BarCfD
144+
145+
// CHECK-TBD-DAG: s4Core3PubCMa
146+
// CHECK-TBD-DAG: s4Core3PubCMu
147+
// CHECK-TBD-DAG: s4Core3PubCMn
148+
// CHECK-TBD-DAG: s4Core3PubCMo
149+
// CHECK-TBD-DAG: s4Core3PubCfd
150+
// CHECK-TBD-DAG: s4Core3PubCfD
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-build-swift -module-name=File -package-name Pkg -I%t -emit-sil %s | %FileCheck %s --check-prefix=CHECK-SIL
4+
// RUN: %target-build-swift -module-name=File -package-name Pkg -I%t -emit-sil %s -enable-library-evolution | %FileCheck %s --check-prefix=CHECK-SIL-HID
5+
// RUN: %target-build-swift -module-name=File -package-name Pkg -I%t -emit-sil %s -enable-library-evolution -Xfrontend -experimental-allow-non-resilient-access | %FileCheck %s --check-prefix=CHECK-SIL
6+
// RUN: %target-build-swift -module-name=File -package-name Pkg -I%t -emit-ir %s | %FileCheck %s --check-prefix=CHECK-IR
7+
// RUN: %target-build-swift -module-name=File -package-name Pkg -I%t -emit-ir %s -enable-library-evolution | %FileCheck %s --check-prefix=CHECK-IR-HID
8+
// RUN: %target-build-swift -module-name=File -package-name Pkg -I%t -emit-ir %s -enable-library-evolution -Xfrontend -experimental-allow-non-resilient-access | %FileCheck %s --check-prefix=CHECK-IR
9+
10+
public struct S {
11+
public static var x = "hello world"
12+
}
13+
14+
// S.x.unsafeMutableAddressor
15+
// CHECK-SIL: sil [global_init] @$s4File1SV1xSSvau : $@convention(thin) () -> Builtin.RawPointer {
16+
// S.x.unsafeMutableAddressor
17+
// CHECK-SIL-HID: sil hidden [global_init] @$s4File1SV1xSSvau : $@convention(thin) () -> Builtin.RawPointer {
18+
19+
// CHECK-IR: define swiftcc ptr @"$s4File1SV1xSSvau"()
20+
// CHECK-IR-HID: define hidden swiftcc ptr @"$s4File1SV1xSSvau"()
21+

0 commit comments

Comments
 (0)