@@ -942,11 +942,22 @@ class AvailabilityScopeBuilder : private ASTWalker {
942
942
return true ;
943
943
}
944
944
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
+
945
956
void buildContextsForBodyOfDecl (Decl *D) {
946
957
// Are we already constrained by the deployment target and the declaration
947
958
// doesn't explicitly allow unsafe constructs in its definition, adding
948
959
// new contexts won't change availability.
949
- bool allowsUnsafe = D-> getAttrs (). hasAttribute <SafeAttr>( );
960
+ bool allowsUnsafe = declHasSafeAttr (D );
950
961
if (isCurrentScopeContainedByDeploymentTarget () && !allowsUnsafe)
951
962
return ;
952
963
@@ -4056,6 +4067,8 @@ class ExprAvailabilityWalker : public BaseDiagnosticWalker {
4056
4067
};
4057
4068
} // end anonymous namespace
4058
4069
4070
+ llvm::DenseSet<const Decl *> reportedDecls;
4071
+
4059
4072
static void suggestUnsafeOnEnclosingDecl (
4060
4073
SourceRange referenceRange, const DeclContext *referenceDC) {
4061
4074
if (referenceRange.isInvalid ())
@@ -4073,6 +4086,9 @@ static void suggestUnsafeOnEnclosingDecl(
4073
4086
if (!decl)
4074
4087
return ;
4075
4088
4089
+ if (!reportedDecls.insert (decl).second )
4090
+ return ;
4091
+
4076
4092
if (versionCheckNode.has_value ()) {
4077
4093
// The unsafe construct is inside the body of the entity, so suggest
4078
4094
// @safe(unchecked) on the declaration.
0 commit comments