Skip to content

[NativeAOT] Warn if a post-ILC postprocessing step modifies a managed assembly#26137

Open
rolfbjarne wants to merge 4 commits into
mainfrom
dev/rolf/no-ilc-postprocessing
Open

[NativeAOT] Warn if a post-ILC postprocessing step modifies a managed assembly#26137
rolfbjarne wants to merge 4 commits into
mainfrom
dev/rolf/no-ilc-postprocessing

Conversation

@rolfbjarne

Copy link
Copy Markdown
Member

When the assembly postprocessing pipeline runs after ILC has compiled the
assemblies (the trimmable-static + NativeAOT + PrepareAssemblies reorder), the
managed assemblies are frozen: ILC already consumed them, so any IL modification
at that point is silently lost. This adds a guard that emits a warning if any step
modifies an assembly in that scenario, so such useless modifications are surfaced
instead of going unnoticed.

To avoid spurious warnings, two "modifications" in the post-ILC pass are fixed:

  • ManagedRegistrarStep.ProcessType unconditionally reported the assembly as
    modified. During post-processing it only collects information about trampolines
    already created in the PrepareAssemblies pass (a read-only operation), so it now
    reports the actual modification state and doesn't trigger a redundant save.

  • The NSObject.RegisterToggleRef stub (which only exists to let ILC trim the
    method) was still being applied post-ILC, uselessly modifying the frozen product
    assembly. It's already applied during the PrepareAssemblies pass before ILC runs,
    so it's now skipped once the assemblies are frozen.

Copilot-Session: 2b6450f9-2ad9-4e89-823a-3cc6e2f33f53

… assembly

When the assembly postprocessing pipeline runs after ILC has compiled the
assemblies (the trimmable-static + NativeAOT + PrepareAssemblies reorder), the
managed assemblies are frozen: ILC already consumed them, so any IL modification
at that point is silently lost. This adds a guard that emits a warning if any step
modifies an assembly in that scenario, so such useless modifications are surfaced
instead of going unnoticed.

To avoid spurious warnings, two "modifications" in the post-ILC pass are fixed:

* ManagedRegistrarStep.ProcessType unconditionally reported the assembly as
  modified. During post-processing it only *collects* information about trampolines
  already created in the PrepareAssemblies pass (a read-only operation), so it now
  reports the actual modification state and doesn't trigger a redundant save.

* The NSObject.RegisterToggleRef stub (which only exists to let ILC trim the
  method) was still being applied post-ILC, uselessly modifying the frozen product
  assembly. It's already applied during the PrepareAssemblies pass before ILC runs,
  so it's now skipped once the assemblies are frozen.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2b6450f9-2ad9-4e89-823a-3cc6e2f33f53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a guard for NativeAOT builds to warn when any post-ILC assembly postprocessing step modifies managed assemblies (since those IL changes are no longer consumed by ILC), and adjusts two known sources of spurious “modifications” to avoid false positives.

Changes:

  • Emit a warning in the assembly-preparer when any assemblies are modified during NativeAOT post-processing (post-ILC scenario).
  • Ensure ManagedRegistrarStep.ProcessType reports modification state more accurately for the post-processing pass.
  • Skip applying the NSObject.RegisterToggleRef stub during post-processing (it’s only useful pre-ILC).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
tools/dotnet-linker/Steps/ManagedRegistrarStep.cs Avoid post-processing IL mutations and refine “modified” reporting for registrar-generated trampolines.
tools/assembly-preparer/AssemblyPreparer.cs Add a NativeAOT post-processing warning when any managed assemblies are modified after ILC.

Comment thread tools/dotnet-linker/Steps/ManagedRegistrarStep.cs
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

rolfbjarne and others added 2 commits July 17, 2026 15:06
… path

The 'modified' flag in ManagedRegistrarStep.ProcessType was only set by
CreateUnmanagedCallersMethod, but the factory-method code path also mutates
the assembly (adding _Xamarin_ConstructNSObject/_Xamarin_ConstructINativeObject
methods and interface implementations) without flipping 'modified'. For
non-trimmed (Copy) assemblies this meant the assembly action was never
switched from Copy to Save, so those IL changes could be silently dropped.

Make ImplementConstructNSObjectFactoryMethod and
ImplementConstructINativeObjectFactoryMethod return whether they modified the
assembly, and propagate that into 'modified' in ProcessType.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@rolfbjarne
rolfbjarne marked this pull request as ready for review July 17, 2026 13:08
@rolfbjarne
rolfbjarne enabled auto-merge (squash) July 17, 2026 13:10
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

✅ API diff for current PR / commit

NET (empty diffs)

✅ API diff vs stable

NET (empty diffs)

ℹ️ Generator diff

Generator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes)

Pipeline on Agent
Hash: f2f51e56d13b963324a92c774366784bb2495ee1 [PR build]

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

🔥 [CI Build #f2f51e5] Test results 🔥

Test results

❌ Tests failed on VSTS: test results

2 tests crashed, 1 tests failed, 186 tests passed.

Failures

❌ dotnettests tests (tvOS)

🔥 Failed catastrophically on VSTS: test results - dotnettests_tvos (no summary found).

Html Report (VSDrops) Download

❌ linker tests (iOS)

🔥 Failed catastrophically on VSTS: test results - linker_ios (no summary found).

Html Report (VSDrops) Download

❌ Tests on macOS Tahoe (26) tests

1 tests failed, 4 tests passed.

Failed tests

  • MacCatalyst/maccatalyst-arm64 monotouch-test: Failed (exit code 1)
    • [FAIL] CreateResponseAuth : ObjCRuntime.RuntimeException : Failed to lookup the required marshalling information.

Html Report (VSDrops) Download

Successes

✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download
✅ cecil: All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (iOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (MacCatalyst): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (macOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (Multiple platforms): All 1 tests passed. Html Report (VSDrops) Download
✅ framework: All 2 tests passed. Html Report (VSDrops) Download
✅ fsharp: All 4 tests passed. Html Report (VSDrops) Download
✅ generator: All 5 tests passed. Html Report (VSDrops) Download
✅ interdependent-binding-projects: All 4 tests passed. Html Report (VSDrops) Download
✅ introspection: All 4 tests passed. Html Report (VSDrops) Download
✅ linker (MacCatalyst): All 15 tests passed. Html Report (VSDrops) Download
✅ linker (macOS): All 21 tests passed. Html Report (VSDrops) Download
✅ linker (tvOS): All 15 tests passed. Html Report (VSDrops) Download
✅ monotouch (iOS): All 19 tests passed. Html Report (VSDrops) Download
✅ monotouch (MacCatalyst): All 18 tests passed. Html Report (VSDrops) Download
✅ monotouch (macOS): All 19 tests passed. Html Report (VSDrops) Download
✅ monotouch (tvOS): All 19 tests passed. Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
✅ sharpie: All 1 tests passed. Html Report (VSDrops) Download
✅ windows: All 3 tests passed. Html Report (VSDrops) Download
✅ xcframework: All 4 tests passed. Html Report (VSDrops) Download
✅ xtro: All 1 tests passed. Html Report (VSDrops) Download

macOS tests

✅ Tests on macOS Monterey (12): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Ventura (13): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Sonoma (14): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Sequoia (15): All 5 tests passed. Html Report (VSDrops) Download

Linux Build Verification

Linux build succeeded

Pipeline on Agent
Hash: f2f51e56d13b963324a92c774366784bb2495ee1 [PR build]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants