[Lldb-commits] [lldb] [lldb][MSABI] Take offset of vbptr into account (PR #190679)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Apr 6 13:44:37 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Nerixyz (Nerixyz)
<details>
<summary>Changes</summary>
In the MS ABI, the offset found in the virtual base table is relative to the virtual base pointer. See Clang's `MicrosoftCXXABI::emitVBTableDefinition`: https://github.com/llvm/llvm-project/blob/1a0ca1019d214a24b55a45704dc71fa183672362/clang/lib/CodeGen/MicrosoftCXXABI.cpp#L2247-L2261
We previously assumed the offset was relative to the record's start.
For example for `B` in
```cpp
struct Extra {
int e1 = 1;
};
struct A {
int a = 3;
};
struct B : public Extra, public virtual A {
int b = 4;
};
```
the `vbptr` is at offset 8 and inside that table, the offset for `A` is 16 while `A` sits at offset 24 from `B`'s start:
```
> cl main.cpp /GS- /Z7 /nologo /d1reportSingleClassLayoutB
(...)
class B size(32):
+---
0 | +--- (base class Extra)
0 | | e1
| +---
8 | {vbptr}
16 | b
| <alignment member> (size=4)
| <alignment member> (size=4)
+---
+--- (virtual base A)
24 | a
+---
B::$vbtable@:
0 | -8
1 | 16 (Bd(B+8)A) (<- value we read)
```
---
Full diff: https://github.com/llvm/llvm-project/pull/190679.diff
3 Files Affected:
- (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp (+2)
- (modified) lldb/test/API/lang/cpp/diamond/TestCppDiamond.py (+31)
- (modified) lldb/test/API/lang/cpp/diamond/main.cpp (+9)
``````````diff
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index fba6aec296324..12fb975822932 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -313,6 +313,8 @@ static bool GetVBaseBitOffset(VTableContextBase &vtable_ctx,
if (base_offset == INT64_MAX)
return false;
+ if (vtable_ctx.isMicrosoft())
+ base_offset += record_layout.getVBPtrOffset().getQuantity();
bit_offset = base_offset * 8;
return true;
diff --git a/lldb/test/API/lang/cpp/diamond/TestCppDiamond.py b/lldb/test/API/lang/cpp/diamond/TestCppDiamond.py
index 27062c0666a1a..edb60922934de 100644
--- a/lldb/test/API/lang/cpp/diamond/TestCppDiamond.py
+++ b/lldb/test/API/lang/cpp/diamond/TestCppDiamond.py
@@ -107,6 +107,37 @@ def test(self):
# Use variable paths to access the members.
self.expect_var_path("j1.x", type="long", value="1")
+ children = [
+ ValueCheck(
+ type="Extra",
+ children=[
+ ValueCheck(
+ type="short",
+ name="some_value",
+ value="3",
+ )
+ ],
+ ),
+ ValueCheck(
+ type="VBase",
+ children=[ValueCheck(type="int", name="m_value", value="12347")],
+ ),
+ ValueCheck(
+ type="Derived1",
+ children=[
+ ValueCheck(
+ type="VBase",
+ children=[
+ ValueCheck(type="int", name="m_value", value="12347")
+ ],
+ )
+ ],
+ ),
+ ValueCheck(type="long", name="z", value="4"),
+ ]
+ # Test that the virtual bases are correct when v(b)table pointer is offset.
+ self.expect_expr("j3", result_type="Joiner3", result_children=children)
+
@expectedFailureAll
@no_debug_info_test
def test_invalid_member(self):
diff --git a/lldb/test/API/lang/cpp/diamond/main.cpp b/lldb/test/API/lang/cpp/diamond/main.cpp
index fdf2f3d326747..b9546e7a52c9b 100644
--- a/lldb/test/API/lang/cpp/diamond/main.cpp
+++ b/lldb/test/API/lang/cpp/diamond/main.cpp
@@ -20,9 +20,18 @@ struct Joiner2 : public Derived2 {
long y = 2;
};
+struct Extra {
+ short some_value = 3;
+};
+
+struct Joiner3 : public Extra, public virtual VBase, public Derived1 {
+ long z = 4;
+};
+
int main(int argc, const char *argv[]) {
Joiner1 j1;
Joiner2 j2;
+ Joiner3 j3;
Derived2 *d = &j1;
d = &j2; // breakpoint 1
return 0; // breakpoint 2
``````````
</details>
https://github.com/llvm/llvm-project/pull/190679
More information about the lldb-commits
mailing list