`MicrosoftVTableContext.getMethodVFTableLocation` may report an incorrect location for a virtual destructor
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
## Summary
When targeting `x86_64-pc-windows-msvc`, `MicrosoftVTableContext::getMethodVFTableLocation()` reports `MethodVFTableLocation::Index == 0` for a virtual destructor regardless of the destructor's position in the vftable. Other virtual methods appear to report their correct indices. The underlying `VTableLayout` places the destructor at the correct slot and matches `MSVC`. So this appears to be a quirk specific to `MicrosoftVTableContext`
This means that for any class whose virtual destructor is not declared first, the reported index collides with whatever genuinely occupies slot 0. Reproduces on clang 22.1.8 (`ca7933e47d3a3451d81e72ac174dcb5aa28b59d1`).
## Repro
The defect is only observable through the AST API, not via codegen, so some minimal sample that creates a translation unit, walks the AST to find the struct, calls `getVTableContext`, and then dumps the slot information is required. -- I have a vibe coded repro that does that, but my presumption is you'd prefer to not get such a non-minimal sloppy sample dumped in the bug report
I cross-checked against MSVC: `cl /d1reportSingleClassLayoutS repro.cpp` but originally hit this in my ClangSharp (C# bindings for Clang) repro. I initially thought it might've been some binary break I hadn't handled between 21.1.8 and 22.1.8, but was able to reproduce using purely the Clang C++ APIs.
```cpp
struct S {
virtual void A();
virtual void B();
virtual S &operator=(const S &); // virtual copy assignment
virtual operator int(); // virtual conversion operator
virtual ~S(); // trailing virtual destructor
};
```
## Observed
clang's location query returns slot 0 for `~S`, colliding with `A`, while its own `VTableLayout` places `~S` at slot 4:
| Virtual method | `getMethodVFTableLocation().Index` | `VTableLayout` slot (ground truth) |
|---|---|---|
| `A` | 0 | 0 |
| `B` | 1 | 1 |
| `operator=` | 2 | 2 |
| `operator int` | 3 | 3 |
| `~S` (destructor) | **0** | **4** |
## Expected
`getMethodVFTableLocation(GlobalDecl(~S, Dtor_Deleting)).Index` should be `4`, matching both `VTableLayout` and MSVC.
Contributor guide
Research direction
Start by tracing MicrosoftVTableContext::getMethodVFTableLocation() for the GlobalDecl(~S, Dtor_Deleting) case and compare it with the VTableLayout slot. Use the C++ AST API reproduction described in the issue with the trailing virtual destructor, then verify that the reported index is 4 rather than 0 and that other virtual methods remain unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100