@@ -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+
40594072static 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.
0 commit comments