Skip to content

Commit 2f60268

Browse files
committed
Auto merge of #27689 - dotdash:die_odr, r=michaelwoerister
When using a generic enum type that was defined in an external crate, our debuginfo currently claims that the concrete type (e.g. Option<i32>) was defined in the current crate, where it was first used. This means that if there are multiple crates that all use, for example, Option<i32> values, they'll have conflicting debuginfo, each crate claiming to have defined that type. This doesn't cause problems in regular builds, but with LTO enabled, LLVM complains because it tries to merge the debuginfo for those types and sees the ODR violations. Since I couldn't find a way to get the file info for the external crate that actually defined the enum, I'm working around the issue by using "<unknown>" as the file for enum types. We'll want to re-visit and fix this later, but this at least this fixes the ICE. And with the file being unknown instead of wrong, the debuginfo isn't really worse than before either. Fixes #26447
2 parents a49d9ba + d17d2dd commit 2f60268

File tree

1 file changed

+38
-22
lines changed

1 file changed

+38
-22
lines changed

src/librustc_trans/trans/debuginfo/metadata.rs

+38-22
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
6262
pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
6363

6464
// ptr::null() doesn't work :(
65-
const UNKNOWN_FILE_METADATA: DIFile = (0 as DIFile);
66-
const UNKNOWN_SCOPE_METADATA: DIScope = (0 as DIScope);
65+
const NO_FILE_METADATA: DIFile = (0 as DIFile);
66+
const NO_SCOPE_METADATA: DIScope = (0 as DIScope);
6767

6868
const FLAGS_NONE: c_uint = 0;
6969

@@ -565,7 +565,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
565565
&slice_type_name[..],
566566
unique_type_id,
567567
&member_descriptions,
568-
UNKNOWN_SCOPE_METADATA,
568+
NO_SCOPE_METADATA,
569569
file_metadata,
570570
span);
571571
return MetadataCreationResult::new(metadata, false);
@@ -610,7 +610,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
610610
unsafe {
611611
llvm::LLVMDIBuilderCreateSubroutineType(
612612
DIB(cx),
613-
UNKNOWN_FILE_METADATA,
613+
NO_FILE_METADATA,
614614
create_DIArray(DIB(cx), &signature_metadata[..]))
615615
},
616616
false);
@@ -654,7 +654,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
654654
unique_type_id,
655655
&[],
656656
containing_scope,
657-
UNKNOWN_FILE_METADATA,
657+
NO_FILE_METADATA,
658658
codemap::DUMMY_SP)
659659
}
660660

@@ -850,13 +850,6 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
850850
}
851851

852852
pub fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
853-
match debug_context(cx).created_files.borrow().get(full_path) {
854-
Some(file_metadata) => return *file_metadata,
855-
None => ()
856-
}
857-
858-
debug!("file_metadata: {}", full_path);
859-
860853
// FIXME (#9639): This needs to handle non-utf8 paths
861854
let work_dir = cx.sess().working_dir.to_str().unwrap();
862855
let file_name =
@@ -866,6 +859,24 @@ pub fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
866859
full_path
867860
};
868861

862+
file_metadata_(cx, full_path, file_name, &work_dir)
863+
}
864+
865+
pub fn unknown_file_metadata(cx: &CrateContext) -> DIFile {
866+
// Regular filenames should not be empty, so we abuse an empty name as the
867+
// key for the special unknown file metadata
868+
file_metadata_(cx, "", "<unknown>", "")
869+
870+
}
871+
872+
fn file_metadata_(cx: &CrateContext, key: &str, file_name: &str, work_dir: &str) -> DIFile {
873+
match debug_context(cx).created_files.borrow().get(key) {
874+
Some(file_metadata) => return *file_metadata,
875+
None => ()
876+
}
877+
878+
debug!("file_metadata: file_name: {}, work_dir: {}", file_name, work_dir);
879+
869880
let file_name = CString::new(file_name).unwrap();
870881
let work_dir = CString::new(work_dir).unwrap();
871882
let file_metadata = unsafe {
@@ -874,8 +885,8 @@ pub fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
874885
};
875886

876887
let mut created_files = debug_context(cx).created_files.borrow_mut();
877-
created_files.insert(full_path.to_string(), file_metadata);
878-
return file_metadata;
888+
created_files.insert(key.to_string(), file_metadata);
889+
file_metadata
879890
}
880891

881892
/// Finds the scope metadata node for the given AST node.
@@ -1226,7 +1237,7 @@ fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
12261237
tuple_llvm_type,
12271238
&tuple_name[..],
12281239
unique_type_id,
1229-
UNKNOWN_SCOPE_METADATA),
1240+
NO_SCOPE_METADATA),
12301241
tuple_llvm_type,
12311242
TupleMDF(TupleMemberDescriptionFactory {
12321243
component_types: component_types.to_vec(),
@@ -1569,9 +1580,14 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
15691580
-> RecursiveTypeDescription<'tcx> {
15701581
let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
15711582

1572-
let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, enum_def_id);
1573-
let loc = span_start(cx, definition_span);
1574-
let file_metadata = file_metadata(cx, &loc.file.name);
1583+
let (containing_scope, _) = get_namespace_and_span_for_item(cx, enum_def_id);
1584+
// FIXME: This should emit actual file metadata for the enum, but we
1585+
// currently can't get the necessary information when it comes to types
1586+
// imported from other crates. Formerly we violated the ODR when performing
1587+
// LTO because we emitted debuginfo for the same type with varying file
1588+
// metadata, so as a workaround we pretend that the type comes from
1589+
// <unknown>
1590+
let file_metadata = unknown_file_metadata(cx);
15751591

15761592
let variants = &enum_type.ty_adt_def().unwrap().variants;
15771593

@@ -1612,7 +1628,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
16121628
DIB(cx),
16131629
containing_scope,
16141630
name.as_ptr(),
1615-
UNKNOWN_FILE_METADATA,
1631+
NO_FILE_METADATA,
16161632
UNKNOWN_LINE_NUMBER,
16171633
bytes_to_bits(discriminant_size),
16181634
bytes_to_bits(discriminant_align),
@@ -1758,7 +1774,7 @@ fn set_members_of_composite_type(cx: &CrateContext,
17581774
DIB(cx),
17591775
composite_type_metadata,
17601776
member_name.as_ptr(),
1761-
UNKNOWN_FILE_METADATA,
1777+
NO_FILE_METADATA,
17621778
UNKNOWN_LINE_NUMBER,
17631779
bytes_to_bits(member_size),
17641780
bytes_to_bits(member_align),
@@ -1801,7 +1817,7 @@ fn create_struct_stub(cx: &CrateContext,
18011817
DIB(cx),
18021818
containing_scope,
18031819
name.as_ptr(),
1804-
UNKNOWN_FILE_METADATA,
1820+
NO_FILE_METADATA,
18051821
UNKNOWN_LINE_NUMBER,
18061822
bytes_to_bits(struct_size),
18071823
bytes_to_bits(struct_align),
@@ -1862,7 +1878,7 @@ pub fn create_global_var_metadata(cx: &CrateContext,
18621878
let loc = span_start(cx, span);
18631879
(file_metadata(cx, &loc.file.name), loc.line as c_uint)
18641880
} else {
1865-
(UNKNOWN_FILE_METADATA, UNKNOWN_LINE_NUMBER)
1881+
(NO_FILE_METADATA, UNKNOWN_LINE_NUMBER)
18661882
};
18671883

18681884
let is_local_to_unit = is_node_local_to_unit(cx, node_id);

0 commit comments

Comments
 (0)