Commit Graph

112 Commits

Author SHA1 Message Date
Gábor Horváth
35b5c817b2 Merge pull request #83520 from Xazax-hun/check-safety-function-types 2025-08-08 06:39:39 +01:00
Gabor Horvath
402ad33463 [StrictMemorySafety] Check the safety of return types of calls
Previously, we skipped checking the return type of a function for safety
as we expected to warn at the use of the returned value:

  let x = returnsUnsafe()
  usesUnsafe(x) // warn here

Unfortunately, this resulted in missing some unsafe constructs that can
introduce memory safety issues when the use of the return value had a
different shape resulting in false negatives for cases like:

  return returnsUnsafe()

or

  usesUnsafe(returnsUnsafe())

This PR changes the analysis to always take return types of function
calls into account.

rdar://157237301
2025-08-05 12:16:44 +01:00
Allan Shortlidge
491a43a66b AST: Re-baseline MemorySafetyAttributes feature. 2025-07-31 10:21:55 -07:00
Doug Gregor
f64516b01d [Strict memory safety] "unsafe" expression never propagates unsafe outward
In the effects checker, we were propagating the "has an unsafe use
site" outside of an `unsafe` expression. The result of this is that we
would not produce a warning for silly expressions like `unsafe unsafe
ptr.pointee`, where the first (outer) `unsafe` is unnecessary. Stop
propagating that bit so we properly diagnose the spurious "unsafe".

Fixes issue #82315 / rdar://153672668.
2025-07-16 12:44:08 -07:00
Doug Gregor
1142fa3bdd [Strict memory safety] Eliminate spurious warnings with synthesized Codable
When synthesizing code for Codable conformances involving unsafe types,
make sure to wrap the resulting expressions in "unsafe" when strict memory safety is enabled.

Tweak the warning-emission logic to suppress warnings about spurious
"unsafe" expressions when the compiler generated the "unsafe" itself,
so we don't spam the developer with warnings they can't fix. Also make
the checking for other suppression considerations safe when there are
no source locations, eliminating a potential assertion.

Fixes rdar://153665692.
2025-07-10 09:03:04 -07:00
Doug Gregor
35628cb503 [Strict memory safety] Fix "unsafe" checking for the for..in loop
The `$generator` variable we create for the async for..in loop is
`nonisolated(unsafe)`, so ensure that we generate an `unsafe`
expression when we use it. This uncovered some inconsistencies in how
we do `unsafe` checking for for..in loops, so fix those.

Fixes rdar://154775389.
2025-07-09 16:19:14 -07:00
Anthony Latsis
1f89bb6a94 Merge pull request #82452 from swiftlang/jepa2
Sema: Fix the insertion location for conformances attributes
2025-06-26 21:38:41 +01:00
Anthony Latsis
ad8c52237c Sema: Fix the insertion location for conformances attributes 2025-06-24 14:49:03 +01:00
Doug Gregor
0e3da0e499 Allow '@unsafe' on import declarations to silence '@preconcurrency' warning
'@preconcurrency' imports open up memory safety holes with respect to
Sendable, which are diagnosed under strict memory safety + strict
concurrency checking. Allow one to write '@unsafe' on those imports to
silence the diagnostic about it.
2025-06-23 19:06:14 -07:00
Doug Gregor
6ba48f2738 [Strict memory safety] Adjust "unsafe" location for string interpolations
String interpolations can end up being unsafe in the call to
appendInterpolation when it's provided with unsafe types. Move the
location of the proposed "unsafe" out to the string interpolation
itself in these cases, which properly suppresses the warning.

Fixes rdar://151799777.
2025-06-02 12:36:36 -07:00
Doug Gregor
5c3faaaf92 Merge pull request #81884 from DougGregor/unsafe-for-loop-uses
[Strict memory safety] Show issues with unsafe constructs in the for..in loop
2025-05-30 23:28:53 -07:00
Doug Gregor
efacceeacd [Strict memory safety] Show issues with unsafe constructs in the for..in loop
We weren't showing the unsafe uses when we determine that a for..in
loop is unsafe. Do so, which generally means complaining about `next()`
being unsafe. Fixes rdar://151237127
2025-05-30 18:44:11 -07:00
Doug Gregor
9af5884555 [Strict memory safety] Improve Fix-Its for implied conformances
The Fix-It was adding @unsafe prior to the extension, which is
incorrect. Make sure we apply @unsafe at the right location for the
explicit conformance.

Fixes rdar://151800162
2025-05-30 17:41:10 -07:00
Doug Gregor
6a800c98b5 Add addition test case for "if case unsafe" 2025-05-22 11:07:13 +01:00
Doug Gregor
abad2fae0f Make the optional feature StrictMemorySafety migratable
This feature is essentially self-migrating, but fit it into the
migration flow by marking it as migratable, adding
`-strict-memory-safety:migrate`, and introducing a test.
2025-05-22 11:07:13 +01:00
Doug Gregor
d5476aeda0 Improve diagnostic for unsafe call arguments
Use the argument type rather than the (potentially generic) parameter type.
2025-05-21 13:46:17 +01:00
Doug Gregor
d4dc36d2f3 [Strict memory safety] Lift "unsafe" in pattern match expressions
When an "unsafe" expression is used as the case expression, lift it up
so it also covers the synthesized matching expression (`=~`). This
eliminates some unsuppressible strict memory safety warnings.

Fixes rdar://151731850.
2025-05-21 13:46:17 +01:00
shiz
d12cb84586 [Parse] Avoid parsing unsafe expression before binary or postfix op (#81429)
rdar://150751248
2025-05-14 10:02:58 +01:00
Doug Gregor
1b94c3b3d6 Always emit "unsafe does not cover any unsafe constructs" warning
Check for unsafe constructs in all modes, so that we can emit the
"unsafe does not cover any unsafe constructs" warning consistently.
One does not need to write "unsafe" outside of strict memory safety
mode, but if you do... it needs to cover unsafe behavior.
2025-04-25 23:22:09 -07:00
Doug Gregor
ee9487b86f [Strict memory safety] Provide argument-specific diagnostics for calls
Similar to what we do for 'throws' checking, perform argument-specific
checking for unsafe call arguments. This provides more detailed failures:

```
example.swift:18:3: warning: expression uses unsafe constructs but is not
marked with 'unsafe' [#StrictMemorySafety]
16 |   x.f(a: 0, b: 17, c: nil)
17 |
18 |   x.f(a: 0, b: 17, c: &i)
   |   |                   `- note: argument 'c' in call to instance
method 'f' has unsafe type 'UnsafePointer<Int>?'
   |   `- warning: expression uses unsafe constructs but is not marked
with 'unsafe' [#StrictMemorySafety]
19 |   unsafeF()
20 | }
```

It also means that we won't complain for `nil` or `Optional.none`
arguments passed to unsafe types, which eliminates some false
positives, and won't complain about unsafe result types when there is
a call---because we'd still get complaints later about the
actually-unsafe bit, which is using those results.

Fixes rdar://149629670.
2025-04-25 21:54:19 -07:00
Anthony Latsis
2cd90bdd69 AST: Quote attributes more consistently in DiagnosticsSema.def 2025-04-22 18:23:36 +01:00
Doug Gregor
b7d41a55a5 [Strict memory safety] Treat the implicit call to a 'defer' function as implicitly 'unsafe'
This eliminates stray warnings.
2025-04-19 21:57:12 -07:00
Doug Gregor
8ec52c825c [Strict memory safety] Nested types are safe/unsafe independent of their enclosing type
When determining whether a nested type is safe, don't consider whether
its enclosing type is safe. They're independent.
2025-04-19 09:49:22 -07:00
Doug Gregor
0405f61207 [Strict memory safety] Only diagnose unsafe types in the canonical type
Typealiases involving unsafe types that resolve to safe types
should not be diagnosed.
2025-04-18 18:43:27 -07:00
Doug Gregor
c522138987 [Strict memory safety] Union member accessors are always unsafe
Union member accessors have no way to know what the "active field" is,
so consider them to always be unsafe.
2025-04-02 16:59:17 -07:00
Doug Gregor
b182c96bd7 Print diagnostic group names by default
Print diagnostic groups as part of the LLVM printer in the same manner as the
Swift one does, always. Make `-print-diagnostic-groups` an inert option, since we
always print diagnostic group names with the `[#GroupName]` syntax.

As part of this, we no longer render the diagnostic group name as part
of the diagnostic *text*, instead leaving it up to the diagnostic
renderer to handle the category appropriately. Update all of the tests
that were depending on `-print-diagnostic-groups` putting it into the
text to instead use the `{{documentation-file=<file name>}}`
diagnostic verification syntax.
2025-03-29 15:40:56 -07:00
Doug Gregor
8a8e108cae Stop propagating @unsafe/@safe from type definitions down to their members 2025-03-27 16:48:09 -07:00
Doug Gregor
8789871035 Diagnose @safe @unsafe when used together
Fixes rdar://147943857.
2025-03-27 16:28:44 -07:00
Doug Gregor
d86f41a922 Improve Fix-It for if let x where x is a reference to an unsafe value
When we encounter unsafe code in `if let x`, we would produce a Fix-It
that would change it to the ill-formed `if let unsafe x`. Improve
tracking of the expressions that are synthesized for the right-hand
side of these conditions, so that we can produce a Fix-It that turns
this into the proper

    if let x = unsafe x

Fixes rdar://147944243.
2025-03-27 16:20:30 -07:00
Doug Gregor
90a2b3d8a0 Look through "unsafe" expressions when checking for single-value statements
We were rejecting the use of switch expressions on the right-hand side
of an assignment that was marked `unsafe`. Fixes rdar://147944753.
2025-03-27 09:49:34 -07:00
Doug Gregor
1b2fad1e78 Properly recurse when removing "unsafe" from inlinable code
I forgot that I have to manually recurse in the syntactic rewriter. Do so.
Fixes rdar://147877042
2025-03-25 16:27:37 -07:00
Doug Gregor
9570e1e3a7 [SE-0458] Add fix-it for removing unnecessary "unsafe" keywords 2025-03-18 13:57:16 -07:00
Doug Gregor
4742d2c5db [SE-0458] withoutActuallyEscaping is unsafe for @convention(block)
The implementation of `withoutActuallyEscaping` for `@convention(block)`
functions cannot verify at runtime that the function did not actually
escape. Diagnose this as unsafe code under strict memory safety checking.

Fixes rdar://139994149.
2025-03-18 13:26:47 -07:00
Doug Gregor
81e8f75f93 [Strict memory safety] Eliminate false cycle when checking nonisolated(unsafe)
Whenc hecking for nonisolated(unsafe), don't evaluate the full isolation
of the entity, because doing so causes a reference cycle.
2025-03-10 22:59:50 -07:00
Doug Gregor
b9cb5ce791 [SE-0458] Disambiguate "unsafe" expression within string interpolation
String interpolation uses an end-of-file token, which we weren't
checking for. Fixes rdar://146493296
2025-03-07 15:10:27 -08:00
Doug Gregor
6cf56e9eb7 SE-0458: Disambiguate postfix expressions vs. unsafe expressions more generally
Handle call-vs-tuple and subscript-vs-collection-expr disambiguation using the
same "no trivia" rule that we used to disambiguite "unsafe.x" (which we
treat as a member access) from "unsafe .x" (which we treat as an unsafe
expression with a leading-dot member access).

Fixes rdar://146459104.
2025-03-07 10:19:26 -08:00
Doug Gregor
be7e87565c [SE-0458] Improved disambiguation for unsafe expressions
Disambiguate `unsafe` in a few more common contexts:
* Before a comma in a list of whatever form
* Before a left brace somewhere that we cannot have a closure

Fixes a few more source compatibility regressions found in the wild,
rdar://146125433.
2025-03-04 12:54:06 -08:00
Doug Gregor
a1180e570c More disambiguation for "unsafe" expressions
Fixes rdar://145870868 / #79704
2025-02-28 14:46:42 -08:00
Doug Gregor
c7f9f2ee3a Rename "Unsafe" diagnostic group to "StrictMemorySafety"
This lines up with the feature name and is more consistent. Thank you,
Anthony, for the suggestion.
2025-02-27 16:21:11 -08:00
Doug Gregor
7c7ea1dfd5 [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.
2025-02-27 09:20:36 -08:00
Doug Gregor
69302f9c1c Merge pull request #79655 from DougGregor/se-0458-condfails
[SE-0458] Improve backward compatibility of generated Swift interfaces
2025-02-27 02:55:24 -08:00
Doug Gregor
ae6ae33201 [SE-0458] Drop "unsafe" effect for for..in loop in inlined code in interfaces
Only compilers can't handle it, so drop it for now.
2025-02-26 22:06:48 -08:00
Doug Gregor
983046f792 [SE-0458] Suppress @unsafe conformances for compilers that can't handle them 2025-02-26 22:06:45 -08:00
Doug Gregor
0c130a995c Make test robust against strict memory safety changes to the standard library 2025-02-26 14:28:22 -08:00
Doug Gregor
998dea25be Update module-trace tests for strictly memory-safe standard libraries 2025-02-26 14:28:20 -08:00
Doug Gregor
939d4d7d91 [SE-0458] Disambiguate "unsafe" expression and for..in effect
Port over the disambiguation code we already had in the new Swift parser
to the existing C++ parser for the "unsafe" expression and for..in effect.
2025-02-26 13:03:55 -08:00
Doug Gregor
b7b5a2a19d [SE-0458] Enable unsafe expressions / attributes / for..in effects by default
With the acceptance of SE-0458, allow the use of unsafe expressions, the
@safe and @unsafe attributes, and the `unsafe` effect on the for..in loop
in all Swift code.

Introduce the `-strict-memory-safety` flag detailed in the proposal to
enable strict memory safety checking. This enables a new class of
feature, an optional feature (that is *not* upcoming or experimental),
and which can be detected via `hasFeature(StrictMemorySafety)`.
2025-02-26 12:30:07 -08:00
Doug Gregor
29d904f09d [SE-0458] Don't warn about unsafe conformances outside of strict safety mode 2025-02-24 17:20:01 -08:00
Doug Gregor
50801f9c05 [SE-0458] Implement "unsafe" effect for the for-in loop
Memory unsafety in the iteration part of the for-in loop (i.e., the part
that works on the iterator) can be covered by the "unsafe" effect on
the for..in loop, before the pattern.
2025-02-23 22:50:39 -08:00
Doug Gregor
6e4f711a55 Merge pull request #79512 from DougGregor/unsafe-storage-checking-generic
Fix declaration context for unsafe storage checking
2025-02-20 02:21:30 -10:00