Fix COM interface method calling wrong method for base/derived classes#128913
Open
elinor-fung wants to merge 3 commits into
Open
Fix COM interface method calling wrong method for base/derived classes#128913elinor-fung wants to merge 3 commits into
elinor-fung wants to merge 3 commits into
Conversation
On main (post-PR#126002), the COM-to-CLR dispatch uses UMEntryThunkData with a baked-in m_pManagedTarget resolved at layout time. When a ComMethodTable is shared between a base and derived class, and the derived class triggers layout first, the target is bound to the derived override. Base class objects then incorrectly dispatch to the derived method. Replace ImplementsInterfaceWithSameSlotsAsParent (which only checked for interface re-implementations in the dispatch map) with a COM-specific CanShareComMethodTableWithParent that also compares the resolved dispatch targets for each interface method. Since ImplementsInterfaceWithSameSlotsAsParent had no other callers, remove it entirely. Fixes dotnet#127512 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Test that COM-to-CLR dispatch correctly resolves virtual method overrides regardless of whether the base or derived class is accessed via COM first. Uses separate type sets to independently validate both orderings within the same process. Regression test for dotnet#127512 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
Tagging subscribers to this area: @dotnet/interop-contrib |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adjusts CoreCLR COM callable wrapper (CCW) vtable sharing behavior so that a derived type cannot reuse a parent’s ComMethodTable when any interface method would resolve to a different target MethodDesc, and adds a regression test covering base-first vs derived-first COM access order.
Changes:
- Add a new COM interop regression test that calls interface methods via the COM vtable and asserts the correct base/derived override is invoked independent of access order.
- Replace the prior “same slots as parent” check with a stricter shareability check that also compares resolved dispatch targets (
MethodDesc*) between parent and child. - Remove the now-unused
MethodTable::ImplementsInterfaceWithSameSlotsAsParenthelper.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/vm/comcallablewrapper.cpp | Adds CanShareComMethodTableWithParent and uses it to gate parent ComMethodTable reuse based on resolved targets. |
| src/coreclr/vm/methodtable.h | Removes declaration of ImplementsInterfaceWithSameSlotsAsParent. |
| src/coreclr/vm/methodtable.cpp | Removes implementation of ImplementsInterfaceWithSameSlotsAsParent. |
| src/tests/Interop/COM/VirtualMethodOverride/VirtualMethodOverrideTest.csproj | Adds a new COM interop test project for the regression scenario. |
| src/tests/Interop/COM/VirtualMethodOverride/VirtualMethodOverrideTest.cs | Adds regression coverage for correct dispatch to base vs derived overrides when COM access order differs. |
Copilot's findings
- Files reviewed: 5/5 changed files
- Comments generated: 2
- Treat null MethodDesc from GetMethodDescForSlot_NoThrow as 'cannot share' instead of skipping the slot. - Move COM interface creation inside try/finally to avoid leaking the first pointer if the second creation throws. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Jun 3, 2026
Open
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
When a COM interface is implemented by a class with a virtual method and a derived class overrides it, they share a
ComMethodTable. With #126002, when aComMethodTablelay out happens, we resolve each interface method into its target method and create a correspondingUMEntryThunkData. This means that if a derived class is used first, its override gets baked into the layout, so the base class will call the wrong method - and vice versa if the base class is used first.This change prevents sharing of a
ComMethodTablebetween a base/derived class if the actual targets of any interface method differ.Found while investigating #127512.
cc @dotnet/appmodel @AaronRobinsonMSFT
Example setup:
If
Derivedis created first, callingBase.DoWorkcallsDerived.DoWork.