Skip to content

Commit d151923

Browse files
committed
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 ```
2 parents 102ab57 + 4cfb700 commit d151923

File tree

4 files changed

+77
-17
lines changed

4 files changed

+77
-17
lines changed

Diff for: src/librustc_llvm/diagnostic.rs

+32-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
pub use self::OptimizationDiagnosticKind::*;
1414
pub use self::Diagnostic::*;
1515

16-
use libc::c_char;
16+
use libc::{c_char, c_uint};
1717
use std::ptr;
1818

1919
use {ValueRef, TwineRef, DebugLocRef, DiagnosticInfoRef};
@@ -69,9 +69,37 @@ impl OptimizationDiagnostic {
6969
}
7070
}
7171

72+
pub struct InlineAsmDiagnostic {
73+
pub cookie: c_uint,
74+
pub message: TwineRef,
75+
pub instruction: ValueRef,
76+
}
77+
78+
impl Copy for InlineAsmDiagnostic {}
79+
80+
impl InlineAsmDiagnostic {
81+
unsafe fn unpack(di: DiagnosticInfoRef)
82+
-> InlineAsmDiagnostic {
83+
84+
let mut opt = InlineAsmDiagnostic {
85+
cookie: 0,
86+
message: ptr::null_mut(),
87+
instruction: ptr::null_mut(),
88+
};
89+
90+
super::LLVMUnpackInlineAsmDiagnostic(di,
91+
&mut opt.cookie,
92+
&mut opt.message,
93+
&mut opt.instruction);
94+
95+
opt
96+
}
97+
}
98+
7299
#[derive(Copy)]
73100
pub enum Diagnostic {
74101
Optimization(OptimizationDiagnostic),
102+
InlineAsm(InlineAsmDiagnostic),
75103

76104
/// LLVM has other types that we do not wrap here.
77105
UnknownDiagnostic(DiagnosticInfoRef),
@@ -82,6 +110,9 @@ impl Diagnostic {
82110
let kind = super::LLVMGetDiagInfoKind(di);
83111

84112
match kind {
113+
super::DK_InlineAsm
114+
=> InlineAsm(InlineAsmDiagnostic::unpack(di)),
115+
85116
super::DK_OptimizationRemark
86117
=> Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di)),
87118

Diff for: src/librustc_llvm/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2049,6 +2049,10 @@ extern {
20492049
function_out: *mut ValueRef,
20502050
debugloc_out: *mut DebugLocRef,
20512051
message_out: *mut TwineRef);
2052+
pub fn LLVMUnpackInlineAsmDiagnostic(DI: DiagnosticInfoRef,
2053+
cookie_out: *mut c_uint,
2054+
message_out: *mut TwineRef,
2055+
instruction_out: *mut ValueRef);
20522056

20532057
pub fn LLVMWriteDiagnosticInfoToString(DI: DiagnosticInfoRef, s: RustStringRef);
20542058
pub fn LLVMGetDiagInfoSeverity(DI: DiagnosticInfoRef) -> DiagnosticSeverity;

Diff for: src/librustc_trans/back/write.rs

+25-16
Original file line numberDiff line numberDiff line change
@@ -336,37 +336,49 @@ struct HandlerFreeVars<'a> {
336336
cgcx: &'a CodegenContext<'a>,
337337
}
338338

339-
unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef,
340-
user: *const c_void,
341-
cookie: c_uint) {
339+
unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext<'a>,
340+
msg: &'b str,
341+
cookie: c_uint) {
342342
use syntax::codemap::ExpnId;
343343

344-
let HandlerFreeVars { cgcx, .. }
345-
= *mem::transmute::<_, *const HandlerFreeVars>(user);
346-
347-
let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s))
348-
.expect("non-UTF8 SMDiagnostic");
349-
350344
match cgcx.lto_ctxt {
351345
Some((sess, _)) => {
352346
sess.codemap().with_expn_info(ExpnId::from_llvm_cookie(cookie), |info| match info {
353-
Some(ei) => sess.span_err(ei.call_site, &msg[]),
354-
None => sess.err(&msg[]),
347+
Some(ei) => sess.span_err(ei.call_site, msg),
348+
None => sess.err(msg),
355349
});
356350
}
357351

358352
None => {
359-
cgcx.handler.err(&msg[]);
353+
cgcx.handler.err(msg);
360354
cgcx.handler.note("build without -C codegen-units for more exact errors");
361355
}
362356
}
363357
}
364358

359+
unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef,
360+
user: *const c_void,
361+
cookie: c_uint) {
362+
let HandlerFreeVars { cgcx, .. }
363+
= *mem::transmute::<_, *const HandlerFreeVars>(user);
364+
365+
let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s))
366+
.expect("non-UTF8 SMDiagnostic");
367+
368+
report_inline_asm(cgcx, &msg[], cookie);
369+
}
370+
365371
unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) {
366372
let HandlerFreeVars { llcx, cgcx }
367373
= *mem::transmute::<_, *const HandlerFreeVars>(user);
368374

369375
match llvm::diagnostic::Diagnostic::unpack(info) {
376+
llvm::diagnostic::InlineAsm(inline) => {
377+
report_inline_asm(cgcx,
378+
llvm::twine_to_string(inline.message).as_slice(),
379+
inline.cookie);
380+
}
381+
370382
llvm::diagnostic::Optimization(opt) => {
371383
let pass_name = str::from_utf8(ffi::c_str_to_bytes(&opt.pass_name))
372384
.ok()
@@ -407,10 +419,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
407419
let fv = &fv as *const HandlerFreeVars as *mut c_void;
408420

409421
llvm::LLVMSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv);
410-
411-
if !cgcx.remark.is_empty() {
412-
llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv);
413-
}
422+
llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv);
414423

415424
if config.emit_no_opt_bc {
416425
let ext = format!("{}.no-opt.bc", name_extra);

Diff for: src/rustllvm/RustWrapper.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,22 @@ LLVMUnpackOptimizationDiagnostic(
894894
*message_out = wrap(&opt->getMsg());
895895
}
896896

897+
extern "C" void
898+
LLVMUnpackInlineAsmDiagnostic(
899+
LLVMDiagnosticInfoRef di,
900+
unsigned *cookie_out,
901+
LLVMTwineRef *message_out,
902+
LLVMValueRef *instruction_out)
903+
{
904+
// Undefined to call this not on an inline assembly diagnostic!
905+
llvm::DiagnosticInfoInlineAsm *ia
906+
= static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di));
907+
908+
*cookie_out = ia->getLocCookie();
909+
*message_out = wrap(&ia->getMsgStr());
910+
*instruction_out = wrap(ia->getInstruction());
911+
}
912+
897913
extern "C" void LLVMWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
898914
raw_rust_string_ostream os(str);
899915
DiagnosticPrinterRawOStream dp(os);

0 commit comments

Comments
 (0)