about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/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 /compiler/rustc_codegen_llvm/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 'compiler/rustc_codegen_llvm/src')
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs25
1 files changed, 16 insertions, 9 deletions
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 74e194750fa..f2cf3b1ef5c 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -437,11 +437,9 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
 
     let DINodeCreationResult { di_node, already_stored_in_typemap } = match *t.kind() {
         ty::Never | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => {
-            DINodeCreationResult::new(build_basic_type_di_node(cx, t), false)
-        }
-        ty::Tuple(elements) if elements.is_empty() => {
-            DINodeCreationResult::new(build_basic_type_di_node(cx, t), false)
+            build_basic_type_di_node(cx, t)
         }
+        ty::Tuple(elements) if elements.is_empty() => build_basic_type_di_node(cx, t),
         ty::Array(..) => build_fixed_size_array_di_node(cx, unique_type_id, t),
         ty::Slice(_) | ty::Str => build_slice_type_di_node(cx, t, unique_type_id),
         ty::Dynamic(..) => build_dyn_type_di_node(cx, t, unique_type_id),
@@ -640,7 +638,10 @@ impl MsvcBasicName for ty::FloatTy {
     }
 }
 
-fn build_basic_type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
+fn build_basic_type_di_node<'ll, 'tcx>(
+    cx: &CodegenCx<'ll, 'tcx>,
+    t: Ty<'tcx>,
+) -> DINodeCreationResult<'ll> {
     debug!("build_basic_type_di_node: {:?}", t);
 
     // When targeting MSVC, emit MSVC style type names for compatibility with
@@ -649,7 +650,13 @@ fn build_basic_type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -
 
     let (name, encoding) = match t.kind() {
         ty::Never => ("!", DW_ATE_unsigned),
-        ty::Tuple(elements) if elements.is_empty() => ("()", DW_ATE_unsigned),
+        ty::Tuple(elements) if elements.is_empty() => {
+            if cpp_like_debuginfo {
+                return build_tuple_type_di_node(cx, UniqueTypeId::for_ty(cx.tcx, t));
+            } else {
+                ("()", DW_ATE_unsigned)
+            }
+        }
         ty::Bool => ("bool", DW_ATE_boolean),
         ty::Char => ("char", DW_ATE_UTF),
         ty::Int(int_ty) if cpp_like_debuginfo => (int_ty.msvc_basic_name(), DW_ATE_signed),
@@ -672,14 +679,14 @@ fn build_basic_type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -
     };
 
     if !cpp_like_debuginfo {
-        return ty_di_node;
+        return DINodeCreationResult::new(ty_di_node, false);
     }
 
     let typedef_name = match t.kind() {
         ty::Int(int_ty) => int_ty.name_str(),
         ty::Uint(uint_ty) => uint_ty.name_str(),
         ty::Float(float_ty) => float_ty.name_str(),
-        _ => return ty_di_node,
+        _ => return DINodeCreationResult::new(ty_di_node, false),
     };
 
     let typedef_di_node = unsafe {
@@ -694,7 +701,7 @@ fn build_basic_type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -
         )
     };
 
-    typedef_di_node
+    DINodeCreationResult::new(typedef_di_node, false)
 }
 
 fn build_foreign_type_di_node<'ll, 'tcx>(