about summary refs log tree commit diff
path: root/src/librustc_codegen_llvm/asm.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-09-28 09:17:28 +0000
committerbors <bors@rust-lang.org>2018-09-28 09:17:28 +0000
commitd623ec6ba32b2d056810c7a8dabdc3e5198a2a53 (patch)
tree794a6e273ec9f299722e53b3d8359db5b18bcf98 /src/librustc_codegen_llvm/asm.rs
parentbd8d030d014a4aa13b9b02b0ce98e2de2a2c54be (diff)
parent0991d2098f9b750331962ad5566200644a00f69e (diff)
Auto merge of #54568 - levex:issue-54130, r=nagisa
codegen_llvm: check inline assembly constraints with LLVM

---%<---
Hey all,

As issue #54130 highlights, constraints are not checked and passing bad constraints to LLVM can crash it since a `Verify()` call is placed inside an assertion (see: `src/llvm/lib/IR/InlineAsm.cpp:39`).

As this is my first PR to the Rust compiler (woot! :tada:), there might be better ways of achieving this result. In particular, I am not too happy about generating an error in codegen; it would be much nicer if we did it earlier. However, @rkruppe [noted on IRC](https://botbot.me/mozilla/rustc/2018-09-25/?msg=104791581&page=1) that this should be fine for an unstable feature and a much better solution than the _status quo_, which is an ICE.

Thanks!
--->%---

LLVM provides a way of checking whether the constraints and the actual
inline assembly make sense. This commit introduces a check before
emitting code for the inline assembly. If LLVM rejects the inline
assembly (or its constraints), then the compiler emits an error E0668
("malformed inline assembly").

Fixes: #54130
Signed-off-by: Levente Kurusa \<lkurusa@acm.org\>
Diffstat (limited to 'src/librustc_codegen_llvm/asm.rs')
-rw-r--r--src/librustc_codegen_llvm/asm.rs8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs
index 5d27f8eab3e..f1bb41bceba 100644
--- a/src/librustc_codegen_llvm/asm.rs
+++ b/src/librustc_codegen_llvm/asm.rs
@@ -30,7 +30,7 @@ pub fn codegen_inline_asm(
     ia: &hir::InlineAsm,
     outputs: Vec<PlaceRef<'ll, 'tcx>>,
     mut inputs: Vec<&'ll Value>
-) {
+) -> bool {
     let mut ext_constraints = vec![];
     let mut output_types = vec![];
 
@@ -97,6 +97,10 @@ pub fn codegen_inline_asm(
         ia.alignstack,
         dialect
     );
+    if r.is_none() {
+        return false;
+    }
+    let r = r.unwrap();
 
     // Again, based on how many outputs we have
     let outputs = ia.outputs.iter().zip(&outputs).filter(|&(ref o, _)| !o.is_indirect);
@@ -117,6 +121,8 @@ pub fn codegen_inline_asm(
         llvm::LLVMSetMetadata(r, kind,
             llvm::LLVMMDNodeInContext(bx.cx.llcx, &val, 1));
     }
+
+    return true;
 }
 
 pub fn codegen_global_asm<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,