about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-12-10 15:01:45 +0100
committerGitHub <noreply@github.com>2022-12-10 15:01:45 +0100
commitab505298ea4cf338403eeaa94c4458b5ad9530db (patch)
tree01e3cb591184e40a8068f5ff4d9cfc34ab27e05a /src/test
parent62160cba7b00e84e92e2e64dc8fa6ba906823585 (diff)
parent7253057887b6de77e6847844311da517d2ada1eb (diff)
downloadrust-ab505298ea4cf338403eeaa94c4458b5ad9530db.tar.gz
rust-ab505298ea4cf338403eeaa94c4458b5ad9530db.zip
Rollup merge of #105482 - wesleywiser:fix_debuginfo_ub, r=tmiasko
Fix invalid codegen during debuginfo lowering

In order for LLVM to correctly generate debuginfo for msvc, we sometimes need to spill arguments to the stack and perform some direct & indirect offsets into the value. Previously, this code always performed those actions, even when not required as LLVM would clean it up during optimization.

However, when MIR inlining is enabled, this can cause problems as the operations occur prior to the spilled value being initialized. To solve this, we first calculate the necessary offsets using just the type which is side-effect free and does not alter the LLVM IR. Then, if we are in a situation which requires us to generate the LLVM IR (and this situation only occurs for arguments, not local variables) then we perform the same calculation again, this time generating the appropriate LLVM IR as we go.

r? `@tmiasko` but feel free to reassign if you want 🙂

Fixes #105386
Diffstat (limited to 'src/test')
-rw-r--r--src/test/codegen/issue-105386-ub-in-debuginfo.rs22
-rw-r--r--src/test/ui/debuginfo/issue-105386-debuginfo-ub.rs20
2 files changed, 42 insertions, 0 deletions
diff --git a/src/test/codegen/issue-105386-ub-in-debuginfo.rs b/src/test/codegen/issue-105386-ub-in-debuginfo.rs
new file mode 100644
index 00000000000..d54ac9e33bc
--- /dev/null
+++ b/src/test/codegen/issue-105386-ub-in-debuginfo.rs
@@ -0,0 +1,22 @@
+// compile-flags: --crate-type=lib -O -Cdebuginfo=2 -Cno-prepopulate-passes
+// min-llvm-version: 15.0 # this test uses opaque pointer notation
+#![feature(stmt_expr_attributes)]
+
+pub struct S([usize; 8]);
+
+#[no_mangle]
+pub fn outer_function(x: S, y: S) -> usize {
+    (#[inline(always)]|| {
+        let _z = x;
+        y.0[0]
+    })()
+}
+
+// Check that we do not attempt to load from the spilled arg before it is assigned to
+// when generating debuginfo.
+// CHECK-LABEL: @outer_function
+// CHECK: [[spill:%.*]] = alloca %"[closure@{{.*.rs}}:9:23: 9:25]"
+// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds %"[closure@{{.*.rs}}:9:23: 9:25]", ptr [[spill]]
+// CHECK-NOT: [[load:%.*]] = load ptr, ptr
+// CHECK: call void @llvm.lifetime.start{{.*}}({{.*}}, ptr [[spill]])
+// CHECK: call void @llvm.memcpy{{.*}}(ptr {{align .*}} [[spill]], ptr {{align .*}} %x
diff --git a/src/test/ui/debuginfo/issue-105386-debuginfo-ub.rs b/src/test/ui/debuginfo/issue-105386-debuginfo-ub.rs
new file mode 100644
index 00000000000..6c6eb5d4e86
--- /dev/null
+++ b/src/test/ui/debuginfo/issue-105386-debuginfo-ub.rs
@@ -0,0 +1,20 @@
+// run-pass
+// compile-flags: --edition 2021 -Copt-level=3 -Cdebuginfo=2 -Zmir-opt-level=3
+
+fn main() {
+    TranslatorI.visit_pre();
+}
+
+impl TranslatorI {
+    fn visit_pre(self) {
+        Some(())
+            .map(|_| self.flags())
+            .unwrap_or_else(|| self.flags());
+    }
+}
+
+struct TranslatorI;
+
+impl TranslatorI {
+    fn flags(&self) {}
+}