Skip to content

Fix exception message for InvalidCastException thrown by unboxing #116672

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 15, 2025

Conversation

jkotas
Copy link
Member

@jkotas jkotas commented Jun 14, 2025

The argument order got swapped recently

Fixes #116650

@Copilot Copilot AI review requested due to automatic review settings June 14, 2025 17:59
Copy link
Contributor

Tagging subscribers to this area: @mangod9
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

@Copilot Copilot AI left a comment

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 corrects the parameter order for the ThrowInvalidCastException QCall, refines the matching managed-side throw helper, and updates VM contracts and GC mode transitions.

  • Swap pSourceType/pTargetType in the QCall signature and remove an obsolete GC transition.
  • Replace multi-parameter QCall import with a private internal call plus a public wrapper in CastHelpers.cs.
  • Standardize contracts in excep.cpp and add a GCX_PREEMP() transition before throwing.

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/coreclr/vm/jithelpers.cpp Swapped QCall signature parameters and removed GCX_COOP().
src/coreclr/vm/excep.cpp Replaced manual CONTRACTL with STANDARD_VM_CONTRACT and added GCX_PREEMP().
src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs Added private QCall import, public wrappers, and rooted overload.
Comments suppressed due to low confidence (1)

src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs:30

  • [nitpick] Directly calling the internal QCall bypasses the public wrapper, which provides a non-return hint and rooting. Consider calling ThrowInvalidCastException instead to maintain consistency and proper GC handling.
ThrowInvalidCastExceptionInternal(RuntimeHelpers.GetMethodTable(fromType), toTypeHnd);

@@ -538,7 +538,7 @@ HCIMPL2(BOOL, JIT_IsInstanceOfException, CORINFO_CLASS_HANDLE type, Object* obj)
}
HCIMPLEND

extern "C" void QCALLTYPE ThrowInvalidCastException(CORINFO_CLASS_HANDLE pTargetType, CORINFO_CLASS_HANDLE pSourceType)
extern "C" void QCALLTYPE ThrowInvalidCastException(CORINFO_CLASS_HANDLE pSourceType, CORINFO_CLASS_HANDLE pTargetType)
Copy link
Member Author

Choose a reason for hiding this comment

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

Introduced in #109135

@@ -11207,11 +11207,7 @@ VOID GetAssemblyDetailInfo(SString &sType,
VOID CheckAndThrowSameTypeAndAssemblyInvalidCastException(TypeHandle thCastFrom,
TypeHandle thCastTo)
{
CONTRACTL {
Copy link
Member Author

Choose a reason for hiding this comment

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

Pre-emptive mode is goodness


[DoesNotReturn]
internal static void ThrowInvalidCastException(object fromType, void* toTypeHnd)
{
ThrowInvalidCastException(RuntimeHelpers.GetMethodTable(fromType), toTypeHnd);
ThrowInvalidCastExceptionInternal(RuntimeHelpers.GetMethodTable(fromType), toTypeHnd);
GC.KeepAlive(fromType);
Copy link
Member Author

Choose a reason for hiding this comment

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

Fixing theoretical unloadability bug

internal static void ThrowInvalidCastException(void* fromTypeHnd, void* toTypeHnd)
{
ThrowInvalidCastExceptionInternal(fromTypeHnd, toTypeHnd);
throw null!; // Provide hint to the inliner that this method does not return
Copy link
Member Author

Choose a reason for hiding this comment

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

Add the same hint here as what's on the other path

@jkotas jkotas merged commit ec11903 into dotnet:main Jun 15, 2025
97 checks passed
@jkotas jkotas deleted the throw-exception branch June 15, 2025 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

InvalidCastException message is "backwards" on .NET 10 preview
2 participants