Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Remove inconsistent UnmanagedCallersOnly delegate construction check - #122906

#122906
Merged
jkotas merged 5 commits into
maindotnet/runtime:mainfrom
copilot/remove-unmanagedcallersonly-checkdotnet/runtime:copilot/remove-unmanagedcallersonly-checkCopy head branch name to clipboard
Jan 7, 2026
Merged

Remove inconsistent UnmanagedCallersOnly delegate construction check#122906
jkotas merged 5 commits into
maindotnet/runtime:mainfrom
copilot/remove-unmanagedcallersonly-checkdotnet/runtime:copilot/remove-unmanagedcallersonly-checkCopy head branch name to clipboard

Conversation

Copilot AI commented Jan 5, 2026

Copy link
Copy Markdown
Contributor

Description

Removes the eager check in COMDelegate::GetDelegateCtor that throws NotSupportedException when attempting to create a delegate to a method with [UnmanagedCallersOnly]. This check is inconsistent with the runtime's policy of lazy validation for UnmanagedCallersOnly methods, which failfast only when actually invoked (e.g., via reflection or calli).

Changes:

  • Removed HasUnmanagedCallersOnlyAttribute() check and exception throw from comdelegate.cpp:2796-2801
  • Removed NegativeTest_ViaDelegate test that verified this exception behavior
  • Removed unused IL methods GetDoubleDelegate and ManagedDoubleCallback from test infrastructure
  • Removed unused resource string NotSupported_UnmanagedCallersOnlyTarget from Strings.resx

Behavior change:

// Before: throws NotSupportedException during delegate creation
var del = new Func<int, int>(MyUnmanagedCallersOnlyMethod);

// After: delegate creation succeeds, failfast occurs on invocation (consistent with reflection path)
var del = new Func<int, int>(MyUnmanagedCallersOnlyMethod);
del(42); // failfast here

Customer Impact

Minimal. The previous exception could be worked around, and invoking an UnmanagedCallersOnly method via delegate already triggers failfast at call time. This aligns the fast delegate construction path with the existing slow path behavior.

Regression

No. Removes a safety check introduced earlier but makes behavior consistent across all delegate construction paths.

Testing

CoreCLR and libraries builds verified. Remaining UnmanagedCallersOnly tests ensure failfast behavior on invocation still works correctly.

Risk

Low. Change removes defensive check but failfast protection remains at invocation time, consistent with other code paths.

Original prompt

This section details on the original issue you should resolve

<issue_title>Delegate fast path construction checks for [UnmanagedCallersOnly] attribute</issue_title>
<issue_description>This is inconsistent with other behavior around UnmanagedCallersOnly where misuse simply triggers a failfast. Consider removing this check.

Check that is inconsistent with policy.

// Do not allow static methods with [UnmanagedCallersOnlyAttribute] to be a delegate target.

Commentary about this, #122656 (comment)

Test code that depends on the check

ldftn int32 InvalidCSharp.CallingUnmanagedCallersOnlyDirectly::ManagedDoubleCallback(int32)
</issue_description>

<agent_instructions>Please delete this check and the related test</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Comment thread src/coreclr/vm/comdelegate.cpp
Copilot AI changed the title [WIP] Remove fast path construction checks for UnmanagedCallersOnly attribute Remove inconsistent UnmanagedCallersOnly delegate construction check Jan 6, 2026
Copilot AI requested a review from jkotas January 6, 2026 00:34
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
@jkotas

jkotas commented Jan 6, 2026

Copy link
Copy Markdown
Member

/azp run runtime-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jkotas
jkotas marked this pull request as ready for review January 6, 2026 03:22
Copilot AI review requested due to automatic review settings January 6, 2026 03:22
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.

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 removes an inconsistent eager validation check that threw NotSupportedException when creating a delegate to a method marked with [UnmanagedCallersOnly]. This aligns delegate construction behavior with the runtime's lazy validation policy, where validation occurs at invocation time (during JIT compilation) rather than at delegate creation time. The failfast protection remains in place through ThrowIfInvalidUnmanagedCallersOnlyUsage called during JIT compilation.

Key changes:

  • Removed eager HasUnmanagedCallersOnlyAttribute() check from delegate constructor path in CoreCLR
  • Removed test that verified the now-removed exception behavior
  • Cleaned up unused IL test methods and resource strings

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src/coreclr/vm/comdelegate.cpp Removed the eager UnmanagedCallersOnly attribute check from GetDelegateCtor that threw NotSupportedException during delegate construction
src/tests/Interop/UnmanagedCallersOnly/UnmanagedCallersOnlyTest.cs Removed NegativeTest_ViaDelegate test that verified the removed NotSupportedException behavior
src/tests/Interop/UnmanagedCallersOnly/InvalidCallbacks.il Removed unused IL methods ManagedDoubleCallback, DoubleImpl, and GetDoubleDelegate that were only used by the removed test
src/libraries/System.Private.CoreLib/src/Resources/Strings.resx Removed unused resource string NotSupported_UnmanagedCallersOnlyTarget that was displayed in the removed exception

@jkotas

jkotas commented Jan 6, 2026

Copy link
Copy Markdown
Member

/azp run runtime-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@AaronRobinsonMSFT

Copy link
Copy Markdown
Member

@jkotas @janvorli Looks like updates to the PAL missed updating the PAL tests.

@AaronRobinsonMSFT AaronRobinsonMSFT added this to the 11.0.0 milestone Jan 6, 2026
@jkotas

jkotas commented Jan 6, 2026

Copy link
Copy Markdown
Member

Looks like updates to the PAL missed updating the PAL tests.

Fixed by #122914

@jkotas

jkotas commented Jan 6, 2026

Copy link
Copy Markdown
Member

/azp run runtime-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jkotas

jkotas commented Jan 6, 2026

Copy link
Copy Markdown
Member

/azp run runtime-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jkotas

jkotas commented Jan 7, 2026

Copy link
Copy Markdown
Member

/ba-g known issue #122345, build analysis is unable to match it for some reason

@jkotas
jkotas merged commit f535ec2 into main Jan 7, 2026
192 of 198 checks passed
@jkotas
jkotas deleted the copilot/remove-unmanagedcallersonly-check branch January 7, 2026 00:34
@github-actions github-actions Bot locked and limited conversation to collaborators Feb 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Delegate fast path construction checks for [UnmanagedCallersOnly] attribute

5 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.