llvm / llvm/llvm-project

`MicrosoftVTableContext.getMethodVFTableLocation` may report an incorrect location for a virtual destructor

Open
#210,608 3 comments 0 reactions 0 assignees View on GitHub
clang:codegen diverges-from:msvc platform:windows
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.