You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Unsafe evolution: add csc flag and msbuild property - #85980
Test plan: #81207
Part of #82791.
Follow up on #84860 - previously I didn't want to add these "APIs" because they can't be marked as experimental, but since then I've realized they are gated on LangVersion=preview anyway which I think is equivalent to experimental.
Azure Pipelines:
Successfully started running 1 pipeline(s).
1 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.
Adds compiler and MSBuild configuration for selecting unsafe-evolution memory-safety rules.
Changes:
Adds the compiler switch and MSBuild task property.
Normalizes the legacy feature flag into compilation options.
Adds command-line, compiler, and SDK integration tests.
Holistic assessment: The implementation is well-tested, but the public option name conflicts with API review and the legacy host path omits the setting.
Promoting the legacy syntax-tree feature into _options makes the opt-in sticky across immutable compilation updates. For example, create a compilation whose tree has updated-memory-safety-rules, then call RemoveAllSyntaxTrees() (or replace it with a tree without the feature): Update passes the already-promoted Version2 options back into this constructor, so the new compilation still uses Version2 even though SyntaxTreeCommonFeatures is now empty. Before this change, SourceModuleSymbol evaluated the current compilation feature and reverted to Version1. Please preserve the originally supplied option and derive the legacy fallback from the current syntax-tree features (including for the language-version diagnostic), and add a remove/replace-tree regression test.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
It establishes durable compiler and MSBuild contracts whose naming and legacy compatibility warrant final maintainer review.
0 open findings
Previously missed (1)
In code that hasn't changed since last review
Place MemorySafetyRulesVersion in alphabetical order
src/Compilers/Core/MSBuildTask/Csc.cs:173
The class explicitly requires C#-specific task parameters to stay alphabetized (Csc.cs:32-34). MemorySafetyRulesVersion should be placed between GenerateFullPaths and ModuleAssemblyName, rather than after Nullable, so future task-property maintenance follows the documented layout.
… rules
- An assembly opts in with `<MemorySafetyRulesVersion>2</MemorySafetyRulesVersion>`, the compiler's own property (dotnet/roslyn#85980). `eng/memorySafetyRules.targets` maps it to the `updated-memory-safety-rules` feature flag until that compiler flows in; delete the mapping then, since the flag will warn (dotnet/roslyn#86224). The existing ref and System.Text.Json test opt-ins move to the property.
- `EnableUnsafeMigrationAnalyzers=true` enables `IL5005`-`IL5010` for `dotnet format`, and `UnsafeMigrationProject`/`UnsafeMigrationTargetFramework` let a migration driver load one target framework of the migrated project. A driver script is at https://gist.github.com/EgorBo/456f9e7d3680a5f9c8e54a168a907187.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: cf859571-aaeb-4ade-b35e-bf2acc951c30
… rules
- An assembly opts in with `<MemorySafetyRulesVersion>2</MemorySafetyRulesVersion>`, the compiler's own property (dotnet/roslyn#85980). `eng/memorySafetyRules.targets` maps it to the `updated-memory-safety-rules` feature flag until that compiler flows in; delete the mapping then, since the flag will warn (dotnet/roslyn#86224). The existing ref and System.Text.Json test opt-ins move to the property.
- `EnableUnsafeMigrationAnalyzers=true` enables `IL5005`-`IL5010` for `dotnet format`, and `UnsafeMigrationProject`/`UnsafeMigrationTargetFramework` let a migration driver load one target framework of the migrated project. A driver script is at https://gist.github.com/EgorBo/456f9e7d3680a5f9c8e54a168a907187.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: cf859571-aaeb-4ade-b35e-bf2acc951c30
EgorBo
added a commit
to EgorBo/runtime-1
that referenced
this pull request
Oct 29, 2026
… rules
- An assembly opts in with `<MemorySafetyRulesVersion>2</MemorySafetyRulesVersion>`, the compiler's own property (dotnet/roslyn#85980). `eng/memorySafetyRules.targets` maps it to the `updated-memory-safety-rules` feature flag until that compiler flows in; delete the mapping then, since the flag will warn (dotnet/roslyn#86224). The existing ref and System.Text.Json test opt-ins move to the property.
- `EnableUnsafeMigrationAnalyzers=true` enables `IL5005`-`IL5010` for `dotnet format`, and `UnsafeMigrationProject`/`UnsafeMigrationTargetFramework` let a migration driver load one target framework of the migrated project. A driver script is at https://gist.github.com/EgorBo/456f9e7d3680a5f9c8e54a168a907187.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: cf859571-aaeb-4ade-b35e-bf2acc951c30
EgorBo
added a commit
to EgorBo/runtime-1
that referenced
this pull request
Oct 29, 2026
… rules
- An assembly opts in with `<MemorySafetyRulesVersion>2</MemorySafetyRulesVersion>`, the compiler's own property (dotnet/roslyn#85980). `eng/memorySafetyRules.targets` maps it to the `updated-memory-safety-rules` feature flag until that compiler flows in; delete the mapping then, since the flag will warn (dotnet/roslyn#86224). The existing ref and System.Text.Json test opt-ins move to the property.
- `EnableUnsafeMigrationAnalyzers=true` enables `IL5005`-`IL5010` for `dotnet format`, and `UnsafeMigrationProject`/`UnsafeMigrationTargetFramework` let a migration driver load one target framework of the migrated project. A driver script is at https://gist.github.com/EgorBo/456f9e7d3680a5f9c8e54a168a907187.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: cf859571-aaeb-4ade-b35e-bf2acc951c30
…ollment (#136621)
Contributes to #131451. Infrastructure only: no library is migrated
here.
## Changes
**Migration tooling (`src/tools/illink`, interop generators)**
- **`UNSAFE_MIGRATION` instead of `#if DEBUG`.** The analyzers and most
fixers were compiled out of Checked, so a Checked toolset ran only the
unsafe-context fixer. They're now built in every configuration but
Release.
- **`UnsafeMigrationFixAllProvider`.** The batch fixer takes the
equivalence key from one arbitrary diagnostic. Under `dotnet format`, a
single unfixable `IL5005` (e.g. on a pointer signature) turned the whole
pass into a silent no-op, and results depended on diagnostic order. Each
diagnostic now gets its own fix. `SynchronizeUnsafeContract`'s remove
and replace-with-`safe` actions share one key.
- **`IL5005` keeps `unsafe` in two more cases.**
- On `extern`/`[LibraryImport]` methods: removing it oscillated with the
`CS9389`/`SYSLIB1064` fixers.
- On members whose inactive `#if` branches contain pointer operations:
those branches can rely on the modifier's lexical context in other
configurations or in other assemblies compiling the same file (e.g.
`Marvin.cs` in CoreLib).
- **Unsafe-context fixer.** It also runs under the legacy rules, to
repair other consumers of a shared file, and it fixes `CS9402` (address
of an unassigned variable, dotnet/roslyn#86017).
- **`CS9392` also covers `StructLayout` `Pack`/`Size`**
(dotnet/roslyn#85921). Otherwise `IL5005` and the field fixer undo each
other.
- **v2 detection through `IModuleSymbol.MemorySafetyRulesVersion`** in
the ILLink analyzers and the interop and System.Text.Json generators.
Reading only the feature flag breaks once `MemorySafetyRulesVersion` is
used. A shared `Common/src/Roslyn/MemorySafetyRulesPolyfills.cs`
extension property stands in for the API (reflection, with the feature
flag as fallback) and replaces three reflection-based copies. Once our
Roslyn reference has the API, call sites bind to it and the shim can be
deleted.
- **Restored `IL5009`/`IL5010` and the add-safety-comment fixer from
#131484.** dotnet/roslyn#85842 only changes IDE0380, which covers member
modifiers (not blocks, expressions or `safe`), and it isn't in our SDK.
The stub is the unsafe-context fixer's `// SAFETY: To be audited`
placeholder, and inline `/* SAFETY: */` markers are recognized.
**Enrollment (`eng/memorySafetyRules.targets`)**
- **Opt in with
`<MemorySafetyRulesVersion>2</MemorySafetyRulesVersion>`,** the
compiler's own property (dotnet/roslyn#85980). Until that compiler flows
in, it maps to the `updated-memory-safety-rules` feature flag.
`AllowUnsafeBlocks` stays each library's own decision, since a library
without unsafe operations needs neither it nor any `safe`/`unsafe`
annotations. Delete the mapping then, since the flag will warn
(dotnet/roslyn#86224). The existing ref and System.Text.Json test
opt-ins move to the property.
- **`EnableUnsafeMigrationAnalyzers=true` enables `IL5005`-`IL5010`**
through `eng/unsafeMigration.globalconfig`; they are disabled by default
and `dotnet format --diagnostics` doesn't enable them.
- **`UnsafeMigrationProject`/`UnsafeMigrationTargetFramework` narrow the
migrated project to one target framework.** `dotnet format -f` can't be
used: it retargets every referenced project too, which fails for
platform-specific TFMs.
## Enrolling a library
The driver lives in a gist:
https://gist.github.com/EgorBo/456f9e7d3680a5f9c8e54a168a907187. Each
step runs `dotnet format analyzers`, and the whole sequence repeats
until nothing changes:
1. `CS9377`/`CS0106`: remove invalid `unsafe`.
2. `IL5005`: remove undocumented `unsafe`.
3. `IL5006`/`SYSLIB1064`/`CS9389`/`CS9392`: add the contracts that have
to be explicit.
4. `CS9364`-`CS9366`/`CS0764`/`CS9390`: synchronize overrides and
partial parts.
5. `CS9360`-`CS9363`/`CS9376`/`CS9402`: introduce unsafe contexts.
6. `IL5009`: add safety comments.
```powershell
# 1. Opt in: add <MemorySafetyRulesVersion>2</MemorySafetyRulesVersion> to src\libraries\Foo\src\Foo.csproj,
# then build it once so its references exist.
.\build.cmd libs -c Release
# 2. Migrate, one pass per target framework.
.\migrate-unsafe-v2.ps1 src\libraries\Foo\src\Foo.csproj -TargetFrameworks net11.0-windows,net11.0-unix,net11.0,netstandard2.0
# 3. Build every target framework, plus the other consumers of the shared files the script lists.
.\dotnet.cmd build src\libraries\Foo\src\Foo.csproj -c Release
```
4. Audit the result:
- Replace each `// SAFETY: To be audited` with the actual reasoning.
- Change `unsafe` to `safe` on `[LibraryImport]`/`extern` members whose
native side is safe, with a `<safety>` doc.
- Write a `<safety>` doc for every `unsafe` member that stays.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: cf859571-aaeb-4ade-b35e-bf2acc951c30
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Test plan: #81207
Part of #82791.
Follow up on #84860 - previously I didn't want to add these "APIs" because they can't be marked as experimental, but since then I've realized they are gated on
LangVersion=previewanyway which I think is equivalent to experimental.Microsoft Reviewers: Open in CodeFlow