Skip to content

Commit 836192b

Browse files
committed
Correctly handle @safe on accessors
1 parent f9b904f commit 836192b

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,11 +942,22 @@ class AvailabilityScopeBuilder : private ASTWalker {
942942
return true;
943943
}
944944

945+
/// Determine whether the given declaration has the @safe attribute.
946+
static bool declHasSafeAttr(Decl *decl) {
947+
if (decl->getAttrs().hasAttribute<SafeAttr>())
948+
return true;
949+
950+
if (auto accessor = dyn_cast<AccessorDecl>(decl))
951+
return declHasSafeAttr(accessor->getStorage());
952+
953+
return false;
954+
}
955+
945956
void buildContextsForBodyOfDecl(Decl *D) {
946957
// Are we already constrained by the deployment target and the declaration
947958
// doesn't explicitly allow unsafe constructs in its definition, adding
948959
// new contexts won't change availability.
949-
bool allowsUnsafe = D->getAttrs().hasAttribute<SafeAttr>();
960+
bool allowsUnsafe = declHasSafeAttr(D);
950961
if (isCurrentScopeContainedByDeploymentTarget() && !allowsUnsafe)
951962
return;
952963

@@ -4056,6 +4067,8 @@ class ExprAvailabilityWalker : public BaseDiagnosticWalker {
40564067
};
40574068
} // end anonymous namespace
40584069

4070+
llvm::DenseSet<const Decl *> reportedDecls;
4071+
40594072
static void suggestUnsafeOnEnclosingDecl(
40604073
SourceRange referenceRange, const DeclContext *referenceDC) {
40614074
if (referenceRange.isInvalid())
@@ -4073,6 +4086,9 @@ static void suggestUnsafeOnEnclosingDecl(
40734086
if (!decl)
40744087
return;
40754088

4089+
if (!reportedDecls.insert(decl).second)
4090+
return;
4091+
40764092
if (versionCheckNode.has_value()) {
40774093
// The unsafe construct is inside the body of the entity, so suggest
40784094
// @safe(unchecked) on the declaration.

test/Unsafe/safe.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ class HasStatics {
3333
static func f(_: UnsafeType) { } // expected-warning{{reference to unsafe struct 'UnsafeType' [Unsafe]}}
3434
}
3535

36+
@unsafe
37+
func unsafeInt() -> Int { 5 }
38+
39+
struct HasProperties {
40+
@safe(unchecked) var computed: Int {
41+
unsafeInt()
42+
}
43+
44+
@unsafe var computedUnsafe: Int {
45+
unsafeInt()
46+
}
47+
}
48+
3649
// Parsing issues
3750
@safe // expected-error{{expected '(' in 'safe' attribute}}
3851
func bad1() { }

0 commit comments

Comments
 (0)