about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2022-11-12 17:25:00 +0100
committerGitHub <noreply@github.com>2022-11-12 17:25:00 +0100
commit798815aec562f04bf9cd0ddbb8e8e03c906fb1cc (patch)
treefc8a80e0b58977246cb21d404bd2d905ccbf0f4d /compiler/rustc_codegen_llvm/src
parentaa05f99001924004757ebd44b54bb6a4dd30c8bd (diff)
parent0e0bcd95cda4293915ecd68921320a0928cdd0bb (diff)
downloadrust-798815aec562f04bf9cd0ddbb8e8e03c906fb1cc.tar.gz
rust-798815aec562f04bf9cd0ddbb8e8e03c906fb1cc.zip
Rollup merge of #104110 - krasimirgg:msan-16, r=nagisa
prevent uninitialized access in black_box for zero-sized-types

Don't read the pointer location in black_box for zero sized types, just emit a memory clobber instead. Addresses  https://github.com/rust-lang/rust/issues/103304 when rust is build against LLVM at HEAD.

Zulip thread: https://rust-lang.zulipchat.com/#narrow/stream/187780-t-compiler.2Fwg-llvm/topic/.28with.20llvm.20at.20HEAD.29.3A.20msan.20error.20in.20core.3A.3Ahint.3A.3Ablack_box
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs15
1 files changed, 12 insertions, 3 deletions
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 825011941a2..cf590a43826 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -340,17 +340,26 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
 
             sym::black_box => {
                 args[0].val.store(self, result);
-
+                let result_val_span = [result.llval];
                 // We need to "use" the argument in some way LLVM can't introspect, and on
                 // targets that support it we can typically leverage inline assembly to do
                 // this. LLVM's interpretation of inline assembly is that it's, well, a black
                 // box. This isn't the greatest implementation since it probably deoptimizes
                 // more than we want, but it's so far good enough.
+                //
+                // For zero-sized types, the location pointed to by the result may be
+                // uninitialized. Do not "use" the result in this case; instead just clobber
+                // the memory.
+                let (constraint, inputs): (&str, &[_]) = if result.layout.is_zst() {
+                    ("~{memory}", &[])
+                } else {
+                    ("r,~{memory}", &result_val_span)
+                };
                 crate::asm::inline_asm_call(
                     self,
                     "",
-                    "r,~{memory}",
-                    &[result.llval],
+                    constraint,
+                    inputs,
                     self.type_void(),
                     true,
                     false,