Skip to content

Commit e8de4c3

Browse files
committed
Fix invalid DWARF for enums when using thinlto
We were setting the same identifier for both the DW_TAG_structure_type and the DW_TAG_variant_part. This becomes a problem when using thinlto becauses it uses the identifier as a key for a map of types that is used to delete duplicates based on the ODR, so one of them is deleted as a duplicate, resulting in invalid DWARF. The DW_TAG_variant_part isn't a standalone type, so it doesn't need an identifier. Fix by omitting its identifier.
1 parent c82834e commit e8de4c3

File tree

4 files changed

+64
-11
lines changed

4 files changed

+64
-11
lines changed

src/librustc_codegen_llvm/debuginfo/metadata.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ impl RecursiveTypeDescription<'ll, 'tcx> {
266266
// ... and attach them to the stub to complete it.
267267
set_members_of_composite_type(cx,
268268
unfinished_type,
269+
metadata_stub,
269270
member_holding_stub,
270271
member_descriptions);
271272
return MetadataCreationResult::new(metadata_stub, true);
@@ -1215,6 +1216,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
12151216
set_members_of_composite_type(cx,
12161217
self.enum_type,
12171218
variant_type_metadata,
1219+
variant_type_metadata,
12181220
member_descriptions);
12191221
vec![
12201222
MemberDescription {
@@ -1256,6 +1258,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
12561258
set_members_of_composite_type(cx,
12571259
self.enum_type,
12581260
variant_type_metadata,
1261+
variant_type_metadata,
12591262
member_descriptions);
12601263
MemberDescription {
12611264
name: if fallback {
@@ -1298,6 +1301,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
12981301
set_members_of_composite_type(cx,
12991302
self.enum_type,
13001303
variant_type_metadata,
1304+
variant_type_metadata,
13011305
variant_member_descriptions);
13021306

13031307
// Encode the information about the null variant in the union
@@ -1358,6 +1362,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
13581362
set_members_of_composite_type(cx,
13591363
self.enum_type,
13601364
variant_type_metadata,
1365+
variant_type_metadata,
13611366
member_descriptions);
13621367

13631368
let niche_value = if i == dataful_variant {
@@ -1698,8 +1703,7 @@ fn prepare_enum_metadata(
16981703
layout.align.abi.bits() as u32,
16991704
DIFlags::FlagZero,
17001705
discriminator_metadata,
1701-
empty_array,
1702-
unique_type_id_str.as_ptr())
1706+
empty_array)
17031707
};
17041708

17051709
// The variant part must be wrapped in a struct according to DWARF.
@@ -1770,14 +1774,16 @@ fn composite_type_metadata(
17701774
set_members_of_composite_type(cx,
17711775
composite_type,
17721776
composite_type_metadata,
1777+
composite_type_metadata,
17731778
member_descriptions);
17741779

17751780
composite_type_metadata
17761781
}
17771782

17781783
fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>,
17791784
composite_type: Ty<'tcx>,
1780-
composite_type_metadata: &'ll DICompositeType,
1785+
metadata_stub: &'ll DICompositeType,
1786+
member_holding_stub: &'ll DICompositeType,
17811787
member_descriptions: Vec<MemberDescription<'ll>>) {
17821788
// In some rare cases LLVM metadata uniquing would lead to an existing type
17831789
// description being used instead of a new one created in
@@ -1788,11 +1794,11 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>,
17881794
{
17891795
let mut composite_types_completed =
17901796
debug_context(cx).composite_types_completed.borrow_mut();
1791-
if composite_types_completed.contains(&composite_type_metadata) {
1797+
if composite_types_completed.contains(&metadata_stub) {
17921798
bug!("debuginfo::set_members_of_composite_type() - \
17931799
Already completed forward declaration re-encountered.");
17941800
} else {
1795-
composite_types_completed.insert(composite_type_metadata);
1801+
composite_types_completed.insert(metadata_stub);
17961802
}
17971803
}
17981804

@@ -1803,7 +1809,7 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>,
18031809
unsafe {
18041810
Some(llvm::LLVMRustDIBuilderCreateVariantMemberType(
18051811
DIB(cx),
1806-
composite_type_metadata,
1812+
member_holding_stub,
18071813
member_name.as_ptr(),
18081814
unknown_file_metadata(cx),
18091815
UNKNOWN_LINE_NUMBER,
@@ -1824,7 +1830,7 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>,
18241830
unsafe {
18251831
let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
18261832
llvm::LLVMRustDICompositeTypeReplaceArrays(
1827-
DIB(cx), composite_type_metadata, Some(type_array), type_params);
1833+
DIB(cx), member_holding_stub, Some(type_array), type_params);
18281834
}
18291835
}
18301836

src/librustc_codegen_llvm/llvm/ffi.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1587,8 +1587,7 @@ extern "C" {
15871587
AlignInBits: u32,
15881588
Flags: DIFlags,
15891589
Discriminator: Option<&'a DIDerivedType>,
1590-
Elements: &'a DIArray,
1591-
UniqueId: *const c_char)
1590+
Elements: &'a DIArray)
15921591
-> &'a DIDerivedType;
15931592

15941593
pub fn LLVMSetUnnamedAddr(GlobalVar: &Value, UnnamedAddr: Bool);

src/rustllvm/RustWrapper.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -723,12 +723,12 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
723723
LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
724724
LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
725725
uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
726-
LLVMMetadataRef Elements, const char *UniqueId) {
726+
LLVMMetadataRef Elements) {
727727
#if LLVM_VERSION_GE(7, 0)
728728
return wrap(Builder->createVariantPart(
729729
unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
730730
SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
731-
DINodeArray(unwrapDI<MDTuple>(Elements)), UniqueId));
731+
DINodeArray(unwrapDI<MDTuple>(Elements))));
732732
#else
733733
abort();
734734
#endif

src/test/debuginfo/enum-thinlto.rs

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// ignore-tidy-linelength
2+
3+
// Require LLVM with DW_TAG_variant_part and a gdb that can read it.
4+
// min-system-llvm-version: 7.0
5+
// min-gdb-version: 8.2
6+
7+
// compile-flags:-g -Z thinlto
8+
9+
// === GDB TESTS ===================================================================================
10+
11+
// gdb-command:run
12+
13+
// gdb-command:print *abc
14+
// gdbr-check:$1 = enum_thinlto::ABC::TheA{x: 0, y: 8970181431921507452}
15+
16+
// === LLDB TESTS ==================================================================================
17+
18+
// lldb-command:run
19+
20+
// lldb-command:print *abc
21+
// lldbg-check:(enum_thinlto::ABC) $0 = ABC { }
22+
23+
#![allow(unused_variables)]
24+
#![feature(omit_gdb_pretty_printer_section)]
25+
#![omit_gdb_pretty_printer_section]
26+
27+
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
28+
// the size of the discriminant value is machine dependent, this has be taken into account when
29+
// datatype layout should be predictable as in this case.
30+
#[derive(Debug)]
31+
enum ABC {
32+
TheA { x: i64, y: i64 },
33+
TheB (i64, i32, i32),
34+
}
35+
36+
fn main() {
37+
let abc = ABC::TheA { x: 0, y: 0x7c7c_7c7c_7c7c_7c7c };
38+
39+
f(&abc);
40+
}
41+
42+
fn f(abc: &ABC) {
43+
zzz(); // #break
44+
45+
println!("{:?}", abc);
46+
}
47+
48+
fn zzz() {()}

0 commit comments

Comments
 (0)