about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2022-03-16 11:03:07 +0100
committerMichael Woerister <michaelwoerister@posteo>2022-03-16 15:57:33 +0100
commit243e2a698c0c6573dc5445b07e0dcb6b0167f876 (patch)
tree58dedb7e0089db204cf27d14729d2120febdfd20
parentd8e564715e0eb17130e99e8fcc92a36fce7feaf5 (diff)
downloadrust-243e2a698c0c6573dc5445b07e0dcb6b0167f876.tar.gz
rust-243e2a698c0c6573dc5445b07e0dcb6b0167f876.zip
debuginfo: Fix ICE when generating name for type that produces a layout error.
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs25
-rw-r--r--src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs16
-rw-r--r--src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr4
-rw-r--r--src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs20
-rw-r--r--src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr4
5 files changed, 67 insertions, 2 deletions
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 4b1563ca3c9..a67414036dc 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -74,9 +74,30 @@ fn push_debuginfo_type_name<'tcx>(
         ty::Float(float_ty) => output.push_str(float_ty.name_str()),
         ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output),
         ty::Adt(def, substs) => {
-            let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).expect("layout error");
+            // `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding.
+            let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() {
+                match tcx.layout_of(ParamEnv::reveal_all().and(t)) {
+                    Ok(layout) => {
+                        if !wants_c_like_enum_debuginfo(layout) {
+                            Some(layout)
+                        } else {
+                            // This is a C-like enum so we don't want to use the fallback encoding
+                            // for the name.
+                            None
+                        }
+                    }
+                    Err(e) => {
+                        // Computing the layout can still fail here, e.g. if the target architecture
+                        // cannot represent the type. See https://github.com/rust-lang/rust/issues/94961.
+                        tcx.sess.fatal(&format!("{}", e));
+                    }
+                }
+            } else {
+                // We are not emitting cpp-like debuginfo or this isn't even an enum.
+                None
+            };
 
-            if def.is_enum() && cpp_like_debuginfo && !wants_c_like_enum_debuginfo(ty_and_layout) {
+            if let Some(ty_and_layout) = layout_for_cpp_like_fallback {
                 msvc_enum_fallback(
                     tcx,
                     ty_and_layout,
diff --git a/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs
new file mode 100644
index 00000000000..78bda28485d
--- /dev/null
+++ b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs
@@ -0,0 +1,16 @@
+// Make sure the compiler does not ICE when trying to generate the debuginfo name of a type that
+// causes a layout error. See https://github.com/rust-lang/rust/issues/94961.
+
+// compile-flags:-C debuginfo=2
+// build-fail
+// error-pattern: too big for the current architecture
+// normalize-stderr-64bit "18446744073709551615" -> "SIZE"
+// normalize-stderr-32bit "4294967295" -> "SIZE"
+
+#![crate_type = "rlib"]
+
+pub struct Foo<T>([T; usize::MAX]);
+
+pub fn foo() -> usize {
+    std::mem::size_of::<Foo<u8>>()
+}
diff --git a/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr
new file mode 100644
index 00000000000..851dca84c3d
--- /dev/null
+++ b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr
@@ -0,0 +1,4 @@
+error: values of the type `[u8; SIZE]` are too big for the current architecture
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs
new file mode 100644
index 00000000000..fdc088dc0f9
--- /dev/null
+++ b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs
@@ -0,0 +1,20 @@
+// Make sure the compiler does not ICE when trying to generate the debuginfo name of a type that
+// causes a layout error.
+// This version of the test already ICE'd before the commit that introduce the ICE described in
+// https://github.com/rust-lang/rust/issues/94961.
+
+// compile-flags:-C debuginfo=2
+// build-fail
+// error-pattern: too big for the current architecture
+// normalize-stderr-64bit "18446744073709551615" -> "SIZE"
+// normalize-stderr-32bit "4294967295" -> "SIZE"
+
+#![crate_type = "rlib"]
+
+pub enum Foo<T> {
+    Bar([T; usize::MAX]),
+}
+
+pub fn foo() -> usize {
+    std::mem::size_of::<Foo<u8>>()
+}
diff --git a/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr
new file mode 100644
index 00000000000..851dca84c3d
--- /dev/null
+++ b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr
@@ -0,0 +1,4 @@
+error: values of the type `[u8; SIZE]` are too big for the current architecture
+
+error: aborting due to previous error
+