diff options
| author | bors <bors@rust-lang.org> | 2015-01-25 16:09:48 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-01-25 16:09:48 +0000 |
| commit | d15192317aa025ff06faa56ca00950fb7ce6ff4b (patch) | |
| tree | f73000348615874afc4caa279494fd3f4bf77bc9 | |
| parent | 102ab57d8085fcb87c02dae929959ccaaa9af548 (diff) | |
| parent | 4cfb70026c91a338518a17579bcd62a32a0a413d (diff) | |
| download | rust-d15192317aa025ff06faa56ca00950fb7ce6ff4b.tar.gz rust-d15192317aa025ff06faa56ca00950fb7ce6ff4b.zip | |
Auto merge of #21518 - Zoxc:asm-err, r=luqmana
Before:
```
error: invalid operand for inline asm constraint 'i' at line 11
```
Note that 11 is not the line the inline assembly appears in.
After:
```
src/arch/x64/multiboot/bootstrap.rs:203:5: 209:9 error: invalid operand for inline asm constraint 'i'
src/arch/x64/multiboot/bootstrap.rs:203 asm! {
src/arch/x64/multiboot/bootstrap.rs:204 [multiboot => %ecx, mod attsyntax]
src/arch/x64/multiboot/bootstrap.rs:205
src/arch/x64/multiboot/bootstrap.rs:206 ljmp {size_of::<Descriptor>() => %i}, $bootstrap.64
src/arch/x64/multiboot/bootstrap.rs:207 }
src/arch/x64/multiboot/bootstrap.rs:208
...
error: aborting due to previous error
```
| -rw-r--r-- | src/librustc_llvm/diagnostic.rs | 33 | ||||
| -rw-r--r-- | src/librustc_llvm/lib.rs | 4 | ||||
| -rw-r--r-- | src/librustc_trans/back/write.rs | 41 | ||||
| -rw-r--r-- | src/rustllvm/RustWrapper.cpp | 16 |
4 files changed, 77 insertions, 17 deletions
diff --git a/src/librustc_llvm/diagnostic.rs b/src/librustc_llvm/diagnostic.rs index db2a569cdef..5d0ae9d1f92 100644 --- a/src/librustc_llvm/diagnostic.rs +++ b/src/librustc_llvm/diagnostic.rs @@ -13,7 +13,7 @@ pub use self::OptimizationDiagnosticKind::*; pub use self::Diagnostic::*; -use libc::c_char; +use libc::{c_char, c_uint}; use std::ptr; use {ValueRef, TwineRef, DebugLocRef, DiagnosticInfoRef}; @@ -69,9 +69,37 @@ impl OptimizationDiagnostic { } } +pub struct InlineAsmDiagnostic { + pub cookie: c_uint, + pub message: TwineRef, + pub instruction: ValueRef, +} + +impl Copy for InlineAsmDiagnostic {} + +impl InlineAsmDiagnostic { + unsafe fn unpack(di: DiagnosticInfoRef) + -> InlineAsmDiagnostic { + + let mut opt = InlineAsmDiagnostic { + cookie: 0, + message: ptr::null_mut(), + instruction: ptr::null_mut(), + }; + + super::LLVMUnpackInlineAsmDiagnostic(di, + &mut opt.cookie, + &mut opt.message, + &mut opt.instruction); + + opt + } +} + #[derive(Copy)] pub enum Diagnostic { Optimization(OptimizationDiagnostic), + InlineAsm(InlineAsmDiagnostic), /// LLVM has other types that we do not wrap here. UnknownDiagnostic(DiagnosticInfoRef), @@ -82,6 +110,9 @@ impl Diagnostic { let kind = super::LLVMGetDiagInfoKind(di); match kind { + super::DK_InlineAsm + => InlineAsm(InlineAsmDiagnostic::unpack(di)), + super::DK_OptimizationRemark => Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di)), diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index eded88bb62e..8c651cf839b 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -2049,6 +2049,10 @@ extern { function_out: *mut ValueRef, debugloc_out: *mut DebugLocRef, message_out: *mut TwineRef); + pub fn LLVMUnpackInlineAsmDiagnostic(DI: DiagnosticInfoRef, + cookie_out: *mut c_uint, + message_out: *mut TwineRef, + instruction_out: *mut ValueRef); pub fn LLVMWriteDiagnosticInfoToString(DI: DiagnosticInfoRef, s: RustStringRef); pub fn LLVMGetDiagInfoSeverity(DI: DiagnosticInfoRef) -> DiagnosticSeverity; diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index b07c2060e69..5e48ce384be 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -336,37 +336,49 @@ struct HandlerFreeVars<'a> { cgcx: &'a CodegenContext<'a>, } -unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef, - user: *const c_void, - cookie: c_uint) { +unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext<'a>, + msg: &'b str, + cookie: c_uint) { use syntax::codemap::ExpnId; - let HandlerFreeVars { cgcx, .. } - = *mem::transmute::<_, *const HandlerFreeVars>(user); - - let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s)) - .expect("non-UTF8 SMDiagnostic"); - match cgcx.lto_ctxt { Some((sess, _)) => { sess.codemap().with_expn_info(ExpnId::from_llvm_cookie(cookie), |info| match info { - Some(ei) => sess.span_err(ei.call_site, &msg[]), - None => sess.err(&msg[]), + Some(ei) => sess.span_err(ei.call_site, msg), + None => sess.err(msg), }); } None => { - cgcx.handler.err(&msg[]); + cgcx.handler.err(msg); cgcx.handler.note("build without -C codegen-units for more exact errors"); } } } +unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef, + user: *const c_void, + cookie: c_uint) { + let HandlerFreeVars { cgcx, .. } + = *mem::transmute::<_, *const HandlerFreeVars>(user); + + let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s)) + .expect("non-UTF8 SMDiagnostic"); + + report_inline_asm(cgcx, &msg[], cookie); +} + unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) { let HandlerFreeVars { llcx, cgcx } = *mem::transmute::<_, *const HandlerFreeVars>(user); match llvm::diagnostic::Diagnostic::unpack(info) { + llvm::diagnostic::InlineAsm(inline) => { + report_inline_asm(cgcx, + llvm::twine_to_string(inline.message).as_slice(), + inline.cookie); + } + llvm::diagnostic::Optimization(opt) => { let pass_name = str::from_utf8(ffi::c_str_to_bytes(&opt.pass_name)) .ok() @@ -407,10 +419,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, let fv = &fv as *const HandlerFreeVars as *mut c_void; llvm::LLVMSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv); - - if !cgcx.remark.is_empty() { - llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv); - } + llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv); if config.emit_no_opt_bc { let ext = format!("{}.no-opt.bc", name_extra); diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index bce73a27699..728ff1461fc 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -894,6 +894,22 @@ LLVMUnpackOptimizationDiagnostic( *message_out = wrap(&opt->getMsg()); } +extern "C" void +LLVMUnpackInlineAsmDiagnostic( + LLVMDiagnosticInfoRef di, + unsigned *cookie_out, + LLVMTwineRef *message_out, + LLVMValueRef *instruction_out) +{ + // Undefined to call this not on an inline assembly diagnostic! + llvm::DiagnosticInfoInlineAsm *ia + = static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di)); + + *cookie_out = ia->getLocCookie(); + *message_out = wrap(&ia->getMsgStr()); + *instruction_out = wrap(ia->getInstruction()); +} + extern "C" void LLVMWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) { raw_rust_string_ostream os(str); DiagnosticPrinterRawOStream dp(os); |
