Skip to content

Commit c0720d5

Browse files
authored
Merge pull request #73686 from apple/elsh/ir-global-accessor
Fix global accessor and class linker errors in package.
2 parents c18d2b1 + 063d159 commit c0720d5

File tree

7 files changed

+210
-16
lines changed

7 files changed

+210
-16
lines changed

include/swift/AST/Decl.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4146,6 +4146,13 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
41464146
/// is built resiliently.
41474147
bool isResilient() const;
41484148

4149+
/// True if the decl is resilient AND also its defining module does
4150+
/// _not_ allow non-resilient access; the module can allow such access
4151+
/// if package optimization is enabled so its client modules within the
4152+
/// same package can have a direct access to this decl even if it's
4153+
/// resilient.
4154+
bool isStrictlyResilient() const;
4155+
41494156
/// Returns whether this decl is accessed non/resiliently at the _use_ site
41504157
/// in \p accessingModule, depending on \p expansion.
41514158
///
@@ -6021,6 +6028,13 @@ class AbstractStorageDecl : public ValueDecl {
60216028
/// property from the given module?
60226029
bool isResilient(ModuleDecl *M, ResilienceExpansion expansion) const;
60236030

6031+
/// True if the decl is resilient AND also its defining module does
6032+
/// _not_ allow non-resilient access; the module can allow such access
6033+
/// if package optimization is enabled so its client modules within the
6034+
/// same package can have a direct access to this decl even if it's
6035+
/// resilient.
6036+
bool isStrictlyResilient() const;
6037+
60246038
/// True if the storage can be referenced by a keypath directly.
60256039
/// Otherwise, its override must be referenced.
60266040
bool isValidKeyPathComponent() const;

include/swift/AST/Module.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,15 @@ class ModuleDecl
779779
return getResilienceStrategy() != ResilienceStrategy::Default;
780780
}
781781

782+
/// True if this module is resilient AND also does _not_ allow
783+
/// non-resilient access; the module can allow such access if
784+
/// package optimization is enabled so its client modules within
785+
/// the same package can have a direct access to decls in this
786+
/// module even if it's built resiliently.
787+
bool isStrictlyResilient() const {
788+
return isResilient() && !allowNonResilientAccess();
789+
}
790+
782791
/// Look up a (possibly overloaded) value set at top-level scope
783792
/// (but with the specified access path, which may come from an import decl)
784793
/// within the current module.

lib/AST/Decl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3022,6 +3022,10 @@ bool Decl::isOutermostPrivateOrFilePrivateScope() const {
30223022
!isInPrivateOrLocalContext(this);
30233023
}
30243024

3025+
bool AbstractStorageDecl::isStrictlyResilient() const {
3026+
return isResilient() && !getModuleContext()->allowNonResilientAccess();
3027+
}
3028+
30253029
bool AbstractStorageDecl::isResilient() const {
30263030
// Check for an explicit @_fixed_layout attribute.
30273031
if (getAttrs().hasAttribute<FixedLayoutAttr>())
@@ -5207,6 +5211,10 @@ bool NominalTypeDecl::isResilient() const {
52075211
return getModuleContext()->isResilient();
52085212
}
52095213

5214+
bool NominalTypeDecl::isStrictlyResilient() const {
5215+
return isResilient() && !getModuleContext()->allowNonResilientAccess();
5216+
}
5217+
52105218
DestructorDecl *NominalTypeDecl::getValueTypeDestructor() {
52115219
if (!isa<StructDecl>(this) && !isa<EnumDecl>(this)) {
52125220
return nullptr;

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 7 additions & 11 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)->isStrictlyResilient() ? 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,7 @@ 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()->isStrictlyResilient())
515511
return Limit::NeverPublic;
516512

517513
break;
@@ -1536,10 +1532,10 @@ SubclassScope SILDeclRef::getSubclassScope() const {
15361532
// FIXME: This is too narrow. Any class with resilient metadata should
15371533
// probably have this, at least for method overrides that don't add new
15381534
// vtable entries.
1539-
bool isResilientClass = classType->isResilient();
1535+
bool isStrictResilientClass = classType->isStrictlyResilient();
15401536

15411537
if (auto *CD = dyn_cast<ConstructorDecl>(decl)) {
1542-
if (isResilientClass)
1538+
if (isStrictResilientClass)
15431539
return SubclassScope::NotApplicable;
15441540
// Initializing entry points do not appear in the vtable.
15451541
if (kind == SILDeclRef::Kind::Initializer)
@@ -1570,14 +1566,14 @@ SubclassScope SILDeclRef::getSubclassScope() const {
15701566
// In the resilient case, we're going to be making symbols _less_
15711567
// visible, so make sure we stop now; final methods can always be
15721568
// called directly.
1573-
if (isResilientClass)
1569+
if (isStrictResilientClass)
15741570
return SubclassScope::Internal;
15751571
}
15761572

15771573
assert(decl->getEffectiveAccess() <= classType->getEffectiveAccess() &&
15781574
"class must be as visible as its members");
15791575

1580-
if (isResilientClass) {
1576+
if (isStrictResilientClass) {
15811577
// The symbol should _only_ be reached via the vtable, so we're
15821578
// going to make it hidden.
15831579
return SubclassScope::Resilient;

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->isStrictlyResilient()) {
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

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 {{(dllexport |protected )?}}swiftcc {{i32|i64}} @"$s4Core3FooC02myB0AA3PubCSgvpfi"() #0 {
35+
36+
// Core.Foo.myFoo.getter
37+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}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 {{(dllexport |protected )?}}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 {{(dllexport |protected )?}}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 {{(dllexport |protected )?}}swiftcc %swift.metadata_response @"$s4Core3FooCMa"
56+
57+
// method lookup function for Core.Foo
58+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc ptr @"$s4Core3FooCMu"(ptr %0, ptr %1)
59+
60+
// dispatch thunk of Core.Foo.myFoo.getter
61+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc {{i32|i64}} @"$s4Core3FooC02myB0AA3PubCSgvgTj"(ptr swiftself %0)
62+
63+
// dispatch thunk of Core.Foo.myFoo.setter
64+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc void @"$s4Core3FooC02myB0AA3PubCSgvsTj"({{i32|i64}} %0, ptr swiftself %1)
65+
66+
// dispatch thunk of Core.Foo.myFoo.modify
67+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc { ptr, ptr } @"$s4Core3FooC02myB0AA3PubCSgvMTj"
68+
69+
// Core.Foo.deinit
70+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc ptr @"$s4Core3FooCfd"(ptr readonly returned swiftself %0)
71+
72+
// Core.Foo.__deallocating_deinit
73+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc void @"$s4Core3FooCfD"(ptr swiftself %0)
74+
75+
76+
// Core.Bar.myBar
77+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc {{i32|i64}} @"$s4Core3BarC02myB0AA3PubCSgvpfi"()
78+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc {{i32|i64}} @"$s4Core3BarC02myB0AA3PubCSgvg"(ptr swiftself %0)
79+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc void @"$s4Core3BarC02myB0AA3PubCSgvs"({{i32|i64}} %0, ptr swiftself %1)
80+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}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 {{(dllexport |protected )?}}swiftcc %swift.metadata_response @"$s4Core3BarCMa"({{i32|i64}} %0)
86+
87+
// method lookup function for Core.Bar
88+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc ptr @"$s4Core3BarCMu"(ptr %0, ptr %1)
89+
90+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc ptr @"$s4Core3BarCfd"(ptr readonly returned swiftself %0)
91+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc void @"$s4Core3BarCfD"(ptr swiftself %0)
92+
93+
// Core.Pub
94+
// type metadata accessor for Core.Pub
95+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc %swift.metadata_response @"$s4Core3PubCMa"({{i32|i64}} %0)
96+
97+
// method lookup function for Core.Pub
98+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc ptr @"$s4Core3PubCMu"(ptr %0, ptr %1)
99+
100+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}swiftcc ptr @"$s4Core3PubCfd"(ptr readnone returned swiftself %0)
101+
// CHECK-IR-DAG: define {{(dllexport |protected )?}}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{{( dllexport)?}}{{( protected)?}} swiftcc ptr @"$s4File1SV1xSSvau"()
20+
// CHECK-IR-HID: define hidden swiftcc ptr @"$s4File1SV1xSSvau"()
21+

0 commit comments

Comments
 (0)