[SE-0458] Suppress "no unsafe operations" warnings outside of strict mode

This is a stop-gap solution to prevent spurious warnings when "unsafe"
expressions and for..in loops are used without strict memory safety.

The full answer is probably to determine where unsafe code is all the time,
so that we can still (correctly) diagnose "no unsafe operations" even outside
of strict memory safety mode.
This commit is contained in:
Doug Gregor
2025-02-27 09:16:55 -08:00
parent 8e87541b93
commit 7c7ea1dfd5
2 changed files with 24 additions and 1 deletions

View File

@@ -4309,7 +4309,8 @@ private:
Ctx.Diags.diagnose(S->getForLoc(), diag::for_unsafe_without_unsafe)
.fixItInsert(insertionLoc, "unsafe ");
}
} else if (S->getUnsafeLoc().isValid()) {
} else if (S->getUnsafeLoc().isValid() &&
Ctx.LangOpts.hasFeature(Feature::StrictMemorySafety)) {
// Extraneous "unsafe" on the sequence.
Ctx.Diags.diagnose(S->getUnsafeLoc(), diag::no_unsafe_in_unsafe_for)
.fixItRemove(S->getUnsafeLoc());
@@ -4343,6 +4344,9 @@ private:
}
void diagnoseRedundantUnsafe(UnsafeExpr *E) const {
if (!Ctx.LangOpts.hasFeature(Feature::StrictMemorySafety))
return;
if (auto *SVE = SingleValueStmtExpr::tryDigOutSingleValueStmtExpr(E)) {
// For an if/switch expression, produce a tailored warning.
Ctx.Diags.diagnose(E->getUnsafeLoc(),
@@ -4351,6 +4355,7 @@ private:
.highlight(E->getUnsafeLoc());
return;
}
Ctx.Diags.diagnose(E->getUnsafeLoc(), diag::no_unsafe_in_unsafe);
}

View File

@@ -0,0 +1,18 @@
// RUN: %target-typecheck-verify-swift -print-diagnostic-groups
@unsafe func unsafeFunc() { }
@unsafe
struct UnsafeType { }
protocol P { }
struct X: @unsafe P { }
func acceptP<T: P>(_: T) { }
func testItAll(ut: UnsafeType, x: X, i: Int) {
_ = unsafe ut
unsafe acceptP(x)
_ = unsafe i
}