about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_gcc/src/debuginfo.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/debuginfo.rs1
-rw-r--r--tests/debuginfo/zst-interferes-with-prologue.rs72
6 files changed, 86 insertions, 2 deletions
diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs
index d770da5a8c4..f2ae9f9c8a6 100644
--- a/compiler/rustc_codegen_gcc/src/debuginfo.rs
+++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs
@@ -48,6 +48,10 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> {
     fn set_dbg_loc(&mut self, dbg_loc: Self::DILocation) {
         self.location = Some(dbg_loc);
     }
+
+    fn clear_dbg_loc(&mut self) {
+        self.location = None;
+    }
 }
 
 /// Generate the `debug_context` in an MIR Body.
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index f5d6fc6f080..842212ac05d 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -1,8 +1,8 @@
 #![doc = include_str!("doc.md")]
 
 use std::cell::{OnceCell, RefCell};
-use std::iter;
 use std::ops::Range;
+use std::{iter, ptr};
 
 use libc::c_uint;
 use rustc_codegen_ssa::debuginfo::type_names;
@@ -209,6 +209,12 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> {
         }
     }
 
+    fn clear_dbg_loc(&mut self) {
+        unsafe {
+            llvm::LLVMSetCurrentDebugLocation2(self.llbuilder, ptr::null());
+        }
+    }
+
     fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) {
         gdb::insert_reference_to_gdb_debug_scripts_section_global(self)
     }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 3bf4d496408..e84ab0aa538 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1041,7 +1041,7 @@ unsafe extern "C" {
     pub fn LLVMDisposeBuilder<'a>(Builder: &'a mut Builder<'a>);
 
     // Metadata
-    pub fn LLVMSetCurrentDebugLocation2<'a>(Builder: &Builder<'a>, Loc: &'a Metadata);
+    pub fn LLVMSetCurrentDebugLocation2<'a>(Builder: &Builder<'a>, Loc: *const Metadata);
 
     // Terminators
     pub fn LLVMBuildRetVoid<'a>(B: &Builder<'a>) -> &'a Value;
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 75692540c03..ab08ef72a69 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -547,6 +547,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         self.set_debug_loc(bx, var.source_info);
                         let base =
                             Self::spill_operand_to_stack(operand, Some(var.name.to_string()), bx);
+                        bx.clear_dbg_loc();
 
                         bx.dbg_var_addr(
                             dbg_var,
diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
index 31104e5749b..5fbe97214fb 100644
--- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
@@ -80,6 +80,7 @@ pub trait DebugInfoBuilderMethods: BackendTypes {
         fragment: Option<Range<Size>>,
     );
     fn set_dbg_loc(&mut self, dbg_loc: Self::DILocation);
+    fn clear_dbg_loc(&mut self);
     fn insert_reference_to_gdb_debug_scripts_section_global(&mut self);
     fn set_var_name(&mut self, value: Self::Value, name: &str);
 }
diff --git a/tests/debuginfo/zst-interferes-with-prologue.rs b/tests/debuginfo/zst-interferes-with-prologue.rs
new file mode 100644
index 00000000000..09041a3bb72
--- /dev/null
+++ b/tests/debuginfo/zst-interferes-with-prologue.rs
@@ -0,0 +1,72 @@
+//@ min-lldb-version: 310
+
+//@ compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:break zst_interferes_with_prologue::Foo::var_return_opt_try
+// gdb-command:run
+
+// gdb-command:print self
+// gdb-command:next
+// gdb-command:print self
+// gdb-command:print $1 == $2
+// gdb-check:true
+
+// === LLDB TESTS ==================================================================================
+
+// lldb-command:b "zst_interferes_with_prologue::Foo::var_return_opt_try"
+// lldb-command:run
+
+// lldb-command:expr self
+// lldb-command:next
+// lldb-command:expr self
+// lldb-command:print $0 == $1
+// lldb-check:true
+
+struct Foo {
+    a: usize,
+}
+
+impl Foo {
+    #[inline(never)]
+    fn get_a(&self) -> Option<usize> {
+        Some(self.a)
+    }
+
+    #[inline(never)]
+    fn var_return(&self) -> usize {
+        let r = self.get_a().unwrap();
+        r
+    }
+
+    #[inline(never)]
+    fn var_return_opt_unwrap(&self) -> Option<usize> {
+        let r = self.get_a().unwrap();
+        Some(r)
+    }
+
+    #[inline(never)]
+    fn var_return_opt_match(&self) -> Option<usize> {
+        let r = match self.get_a() {
+            None => return None,
+            Some(a) => a,
+        };
+        Some(r)
+    }
+
+    #[inline(never)]
+    fn var_return_opt_try(&self) -> Option<usize> {
+        let r = self.get_a()?;
+        Some(r)
+    }
+}
+
+fn main() {
+    let f1 = Foo{ a: 1 };
+    let f2 = Foo{ a: 1 };
+    f1.var_return();
+    f1.var_return_opt_unwrap();
+    f1.var_return_opt_match();
+    f2.var_return_opt_try();
+}