about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-04-23 07:12:52 +0000
committerbors <bors@rust-lang.org>2022-04-23 07:12:52 +0000
commit09064a21b05df8a5f92d34622c467bd037a923fd (patch)
tree754f9126ab09f697df6fb8026c46822551caded0 /src
parent64c5deb0e3a22b93ed1fe5e2a7f2e8d91eea63b9 (diff)
parent8b230086fa4b22c647129a8c84fa0bdfc6d82a0d (diff)
downloadrust-09064a21b05df8a5f92d34622c467bd037a923fd.tar.gz
rust-09064a21b05df8a5f92d34622c467bd037a923fd.zip
Auto merge of #96316 - michaelwoerister:debuginfo-fix-unit-msvc, r=wesleywiser
debuginfo: Emit ZST struct debuginfo for unit type when CPP-like debuginfo is enabled

As already discovered in https://github.com/rust-lang/rust/commit/24a728a8eb4832568509eb757c2374934a76cb98, PDB does not play well with custom basic types. This PR extends to the fix to `()`: Instead of a custom basic type, we treat it like an empty tuple (i.e. it is described as a struct which happens to have no fields).

Before this change anything with a `()` in it would cause trouble, which is especially bad for `*const ()` and `*mut ()` which are often used for opaque pointers. E.g. the test case added in this PR would look like:
```
0:000>  dx _ref
Error: Unable to bind name '_ref'
0:000>  dx _ptr
Error: Unable to bind name '_ptr'
0:000>  dx _local
Error: Unable to bind name '_local'
0:000>  dx _field,d
_field,d         [Type: unit_type::_TypeContainingUnitField]
    [+0x008] _a               : 123 [Type: unsigned int]
    [+0x000] _unit            : Unexpected failure to dereference object
    [+0x000] _b               : 456 [Type: unsigned __int64]
0:000>  dx ((__int64 *)_ptr),x
Error: Unable to bind name '_ptr'
```

With the PR it produces the expected output:
```
0:000>  dx _ref
_ref             : 0x7ff6f2012230 : () [Type: tuple$<> *]
0:000>  dx _ptr
_ptr             : 0x7e8ddffc20 : () [Type: tuple$<> *]
0:000>  dx _local
_local           : () [Type: tuple$<>]
0:000>  dx _field,d
_field,d         [Type: unit_type::_TypeContainingUnitField]
    [+0x008] _a               : 123 [Type: unsigned int]
    [+0x000] _unit            : () [Type: tuple$<>]
    [+0x000] _b               : 456 [Type: unsigned __int64]
0:000>  dx ((__int64 *)_ptr),x
((__int64 *)_ptr),x : 0x7e8ddffc20 : 0x1122334455667788 [Type: __int64 *]
```

r? `@wesleywiser`
Diffstat (limited to 'src')
-rw-r--r--src/test/debuginfo/unit-type.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/test/debuginfo/unit-type.rs b/src/test/debuginfo/unit-type.rs
new file mode 100644
index 00000000000..7aab41a3e7c
--- /dev/null
+++ b/src/test/debuginfo/unit-type.rs
@@ -0,0 +1,71 @@
+// compile-flags:-g
+
+// We only test Rust-aware versions of GDB:
+// min-gdb-version: 8.2
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command: run
+
+// gdb-command: print _ref
+// gdb-check: $1 = (*mut ()) 0x[...]
+
+// gdb-command: print _ptr
+// gdb-check: $2 = (*mut ()) 0x[...]
+
+// gdb-command: print _local
+// gdb-check: $3 = ()
+
+// gdb-command: print _field
+// gdb-check: $4 = unit_type::_TypeContainingUnitField {_a: 123, _unit: (), _b: 456}
+
+// Check that we can cast "void pointers" to their actual type in the debugger
+// gdb-command: print /x *(_ptr as *const u64)
+// gdb-check: $5 = 0x1122334455667788
+
+// === CDB TESTS ===================================================================================
+
+// cdb-command: g
+// cdb-check: Breakpoint 0 hit
+
+// cdb-command: dx _ref
+// cdb-check: _ref             : 0x[...] : () [Type: tuple$<> *]
+
+// cdb-command: dx _ptr
+// cdb-check: _ptr             : 0x[...] : () [Type: tuple$<> *]
+
+// cdb-command: dx _local
+// cdb-check: _local           : () [Type: tuple$<>]
+
+// cdb-command: dx _field,d
+// cdb-check: _field,d         [Type: unit_type::_TypeContainingUnitField]
+// cdb-check:     [+0x[...]] _a               : 123 [Type: unsigned int]
+// cdb-check:     [+0x[...]] _unit            : () [Type: tuple$<>]
+// cdb-check:     [+0x[...]] _b               : 456 [Type: unsigned __int64]
+
+// Check that we can cast "void pointers" to their actual type in the debugger
+// cdb-command: dx ((__int64 *)_ptr),x
+// cdb-check: ((__int64 *)_ptr),x : 0x[...] : 0x1122334455667788 [Type: __int64 *]
+// cdb-check:     0x1122334455667788 [Type: __int64]
+
+struct _TypeContainingUnitField {
+    _a: u32,
+    _unit: (),
+    _b: u64,
+}
+
+fn foo(_ref: &(), _ptr: *const ()) {
+    let _local = ();
+    let _field = _TypeContainingUnitField { _a: 123, _unit: (), _b: 456 };
+
+    zzz(); // #break
+}
+
+fn main() {
+    let pointee = 0x1122_3344_5566_7788i64;
+
+    foo(&(), &pointee as *const i64 as *const ());
+}
+
+#[inline(never)]
+fn zzz() {}