Skip to content

Commit 00bceec

Browse files
authored
Merge pull request #7138 from slavapestov/fix-more-inlineable-bugs
Fix more @_inlineable bugs
2 parents 9424f2b + f2d1599 commit 00bceec

File tree

8 files changed

+104
-58
lines changed

8 files changed

+104
-58
lines changed

lib/SIL/SILDeclRef.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -438,11 +438,6 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
438438
if (isEnumElement())
439439
return SILLinkage::Shared;
440440

441-
// Stored property initializers have hidden linkage, since they are
442-
// not meant to be used from outside of their module.
443-
if (isStoredPropertyInitializer())
444-
return (forDefinition ? SILLinkage::Hidden : SILLinkage::HiddenExternal);
445-
446441
// Declarations imported from Clang modules have shared linkage.
447442
const SILLinkage ClangLinkage = SILLinkage::Shared;
448443

@@ -499,9 +494,16 @@ bool SILDeclRef::isFragile() const {
499494
DeclContext *dc;
500495
if (auto closure = getAbstractClosureExpr())
501496
dc = closure->getLocalContext();
502-
else
497+
else {
503498
dc = getDecl()->getInnermostDeclContext();
504499

500+
// Enum case constructors are serialized if the enum is @_versioned
501+
// or public.
502+
if (isEnumElement())
503+
if (cast<EnumDecl>(dc)->getEffectiveAccess() >= Accessibility::Public)
504+
return true;
505+
}
506+
505507
// This is stupid
506508
return (dc->getResilienceExpansion() == ResilienceExpansion::Minimal);
507509
}

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,27 +77,42 @@ bool TypeChecker::diagnoseInlineableDeclRef(SourceLoc loc,
7777
const ValueDecl *D,
7878
const DeclContext *DC) {
7979
auto expansion = DC->getResilienceExpansion();
80-
if (expansion == ResilienceExpansion::Minimal) {
81-
if (!isa<GenericTypeParamDecl>(D) &&
82-
// Protocol requirements are not versioned because there's no
83-
// global entry point
84-
!(isa<ProtocolDecl>(D->getDeclContext()) && isRequirement(D)) &&
85-
// FIXME: Figure out what to do with typealiases
86-
!isa<TypeAliasDecl>(D) &&
87-
!D->getDeclContext()->isLocalContext() &&
88-
D->hasAccessibility()) {
89-
if (D->getEffectiveAccess() < Accessibility::Public) {
90-
diagnose(loc, diag::resilience_decl_unavailable,
91-
D->getDescriptiveKind(), D->getFullName(),
92-
D->getFormalAccess(), getFragileFunctionKind(DC));
93-
diagnose(D, diag::resilience_decl_declared_here,
94-
D->getDescriptiveKind(), D->getFullName());
95-
return true;
96-
}
97-
}
98-
}
9980

100-
return false;
81+
// Internal declarations referenced from non-inlineable contexts are OK.
82+
if (expansion == ResilienceExpansion::Maximal)
83+
return false;
84+
85+
// Local declarations are OK.
86+
if (D->getDeclContext()->isLocalContext())
87+
return false;
88+
89+
// Type parameters are OK.
90+
if (isa<AbstractTypeParamDecl>(D))
91+
return false;
92+
93+
// Public declarations are OK.
94+
if (D->getEffectiveAccess() >= Accessibility::Public)
95+
return false;
96+
97+
// Enum cases are handled as part of their containing enum.
98+
if (isa<EnumElementDecl>(D))
99+
return false;
100+
101+
// Protocol requirements are not versioned because there's no
102+
// global entry point.
103+
if (isa<ProtocolDecl>(D->getDeclContext()) && isRequirement(D))
104+
return false;
105+
106+
// FIXME: Figure out what to do with typealiases
107+
if (isa<TypeAliasDecl>(D))
108+
return false;
109+
110+
diagnose(loc, diag::resilience_decl_unavailable,
111+
D->getDescriptiveKind(), D->getFullName(),
112+
D->getFormalAccess(), getFragileFunctionKind(DC));
113+
diagnose(D, diag::resilience_decl_declared_here,
114+
D->getDescriptiveKind(), D->getFullName());
115+
return true;
101116
}
102117

103118
void TypeChecker::diagnoseResilientValueConstructor(ConstructorDecl *ctor) {

lib/Sema/TypeCheckAttr.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,12 @@ void AttributeEarlyChecker::visitIBActionAttr(IBActionAttr *attr) {
292292

293293
void AttributeEarlyChecker::visitIBDesignableAttr(IBDesignableAttr *attr) {
294294
if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
295-
NominalTypeDecl *extendedType = ED->getExtendedType()->getAnyNominal();
296-
if (extendedType && !isa<ClassDecl>(extendedType))
297-
return diagnoseAndRemoveAttr(attr, diag::invalid_ibdesignable_extension);
295+
if (auto extendedType = ED->getExtendedType()) {
296+
if (auto *nominalDecl = extendedType->getAnyNominal()) {
297+
if (!isa<ClassDecl>(nominalDecl))
298+
return diagnoseAndRemoveAttr(attr, diag::invalid_ibdesignable_extension);
299+
}
300+
}
298301
}
299302
}
300303

@@ -1770,14 +1773,19 @@ void AttributeChecker::visitSpecializeAttr(SpecializeAttr *attr) {
17701773
attr->setRequirements(DC->getASTContext(), convertedRequirements);
17711774
}
17721775

1776+
static Accessibility getAccessForDiagnostics(const ValueDecl *D) {
1777+
return std::min(D->getFormalAccess(),
1778+
D->getEffectiveAccess());
1779+
}
1780+
17731781
void AttributeChecker::visitFixedLayoutAttr(FixedLayoutAttr *attr) {
17741782
auto *VD = cast<ValueDecl>(D);
17751783

17761784
if (VD->getEffectiveAccess() < Accessibility::Public) {
17771785
TC.diagnose(attr->getLocation(),
17781786
diag::fixed_layout_attr_on_internal_type,
17791787
VD->getName(),
1780-
VD->getFormalAccess())
1788+
getAccessForDiagnostics(VD))
17811789
.fixItRemove(attr->getRangeWithAt());
17821790
attr->setInvalid();
17831791
}
@@ -1800,7 +1808,7 @@ void AttributeChecker::visitVersionedAttr(VersionedAttr *attr) {
18001808
TC.diagnose(attr->getLocation(),
18011809
diag::versioned_attr_with_explicit_accessibility,
18021810
VD->getName(),
1803-
VD->getFormalAccess())
1811+
getAccessForDiagnostics(VD))
18041812
.fixItRemove(attr->getRangeWithAt());
18051813
attr->setInvalid();
18061814
return;

test/SILGen/inlineable_attribute.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,23 @@ public class MyCls {
2424
// CHECK-LABEL: sil [fragile] @_T020inlineable_attribute5MyClsCfD : $@convention(method) (@owned MyCls) -> ()
2525
@_inlineable deinit {}
2626
}
27+
28+
// Make sure enum case constructors for public and versioned enums are
29+
// [fragile].
30+
@_versioned enum MyEnum {
31+
case c(MySt)
32+
}
33+
34+
// CHECK-LABEL: sil shared [transparent] [fragile] [thunk] @_T020inlineable_attribute6MyEnumO1cAcA0C2StVcACmFTc : $@convention(thin) (@thin MyEnum.Type) -> @owned @callee_owned (MySt) -> MyEnum
35+
36+
@_inlineable public func referencesMyEnum() {
37+
_ = MyEnum.c
38+
}
39+
40+
// CHECK-LABEL: sil [transparent] @_T020inlineable_attribute15HasInitializersV1xSivfi : $@convention(thin) () -> Int
41+
42+
public struct HasInitializers {
43+
public let x = 1234
44+
45+
@_inlineable public init() {}
46+
}

test/attr/attr_fixed_layout.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,13 @@ struct Rectangle {
5050
// Diagnostics
5151
//
5252

53-
@_fixed_layout struct InternalStruct {}
53+
@_fixed_layout struct InternalStruct {
5454
// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@_versioned' or public declarations, but 'InternalStruct' is internal}}
5555

56+
@_fixed_layout public struct NestedStruct {}
57+
// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@_versioned' or public declarations, but 'NestedStruct' is internal}}
58+
}
59+
5660
@_fixed_layout fileprivate struct FileprivateStruct {}
5761
// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@_versioned' or public declarations, but 'FileprivateStruct' is fileprivate}}
5862

test/attr/attr_inlineable.swift

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -217,32 +217,29 @@ extension VersionedProtocol {
217217
}
218218
}
219219

220-
protocol InternalProtocol {
221-
associatedtype T
222-
223-
func requirement() -> T
220+
enum InternalEnum {
221+
// expected-note@-1 2{{enum 'InternalEnum' is not '@_versioned' or public}}
222+
case apple
223+
case orange
224224
}
225225

226-
extension InternalProtocol {
227-
func internalMethod() {}
226+
@_inlineable public func usesInternalEnum() {
227+
_ = InternalEnum.apple
228+
// expected-error@-1 {{enum 'InternalEnum' is internal and cannot be referenced from an '@_inlineable' function}}
229+
let _: InternalEnum = .orange
230+
// expected-error@-1 {{enum 'InternalEnum' is internal and cannot be referenced from an '@_inlineable' function}}
231+
}
228232

229-
// FIXME: https://bugs.swift.org/browse/SR-3684
230-
//
231-
// This should either complain that the method cannot be '@_versioned' since
232-
// we're inside an extension of an internal protocol, or if such methods are
233-
// allowed, we should diagnose the reference to 'internalMethod()' from the
234-
// body.
235-
@_inlineable
236-
@_versioned
237-
func versionedMethod() -> T {
238-
internalMethod()
239-
return requirement()
240-
}
233+
@_versioned enum VersionedEnum {
234+
case apple
235+
case orange
236+
// FIXME: Should this be banned?
237+
case pear(InternalEnum)
238+
case persimmon(String)
239+
}
241240

242-
// Ditto, except s/@_versioned/public/.
243-
@_inlineable
244-
public func publicMethod() -> T {
245-
internalMethod()
246-
return requirement()
247-
}
241+
@_inlineable public func usesVersionedEnum() {
242+
_ = VersionedEnum.apple
243+
let _: VersionedEnum = .orange
244+
_ = VersionedEnum.persimmon
248245
}

validation-test/compiler_crashers/28608-swift-typebase-getcanonicaltype.swift renamed to validation-test/compiler_crashers_fixed/28608-swift-typebase-getcanonicaltype.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
// See https://swift.org/LICENSE.txt for license information
66
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
77

8-
// RUN: not --crash %target-swift-frontend %s -emit-ir
8+
// RUN: not %target-swift-frontend %s -emit-ir
99
do{@IBDesignable extension

validation-test/compiler_crashers/28660-false-encountered-error-in-diagnostic-text.swift renamed to validation-test/compiler_crashers_fixed/28660-false-encountered-error-in-diagnostic-text.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
77

88
// REQUIRES: asserts
9-
// RUN: not --crash %target-swift-frontend %s -emit-ir
9+
// RUN: not %target-swift-frontend %s -emit-ir
1010
class C{@_fixed_layout public struct P

0 commit comments

Comments
 (0)