about summary refs log tree commit diff
path: root/src/librustc_codegen_llvm/builder.rs
diff options
context:
space:
mode:
authorLevente Kurusa <lkurusa@acm.org>2018-09-25 20:35:19 +0200
committerLevente Kurusa <lkurusa@acm.org>2018-09-25 20:38:35 +0200
commitfec86c8352d57fd7764d0fa2c4975010c7de793e (patch)
tree76d7eb0fbda781b8ee5a5c6aca645a99d4946d7f /src/librustc_codegen_llvm/builder.rs
parente5c6575801028f5e089ef2e7720aa1af9d452334 (diff)
codegen_llvm: check inline assembly constraints with LLVM
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").

Signed-off-by: Levente Kurusa <lkurusa@acm.org>
Diffstat (limited to 'src/librustc_codegen_llvm/builder.rs')
-rw-r--r--src/librustc_codegen_llvm/builder.rs16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index e3526a5a2ee..afb87e2723f 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -737,7 +737,7 @@ impl Builder<'a, 'll, 'tcx> {
     pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
                          inputs: &[&'ll Value], output: &'ll Type,
                          volatile: bool, alignstack: bool,
-                         dia: AsmDialect) -> &'ll Value {
+                         dia: AsmDialect) -> Option<&'ll Value> {
         self.count_insn("inlineasm");
 
         let volatile = if volatile { llvm::True }
@@ -753,9 +753,17 @@ impl Builder<'a, 'll, 'tcx> {
         debug!("Asm Output Type: {:?}", output);
         let fty = Type::func(&argtys[..], output);
         unsafe {
-            let v = llvm::LLVMRustInlineAsm(
-                fty, asm, cons, volatile, alignstack, dia);
-            self.call(v, inputs, None)
+            // Ask LLVM to verify that the constraints are well-formed.
+            let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons);
+            debug!("Constraint verification result: {:?}", constraints_ok);
+            if constraints_ok == 1 {
+                let v = llvm::LLVMRustInlineAsm(
+                    fty, asm, cons, volatile, alignstack, dia);
+                Some(self.call(v, inputs, None))
+            } else {
+                // LLVM has detected an issue with our constaints, bail out
+                None
+            }
         }
     }