about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAmanieu d'Antras <amanieu@gmail.com>2020-06-09 14:37:59 +0100
committerAmanieu d'Antras <amanieu@gmail.com>2020-06-09 15:01:02 +0100
commit5541f689e9cfc6c1ccdb2277a308bc2e8541ab5e (patch)
tree5a8f9bd2527f03f20cc1b4e53d32cb53540db1cc
parentccac43b86b559e01fa71179af1a838ab94559c75 (diff)
downloadrust-5541f689e9cfc6c1ccdb2277a308bc2e8541ab5e.tar.gz
rust-5541f689e9cfc6c1ccdb2277a308bc2e8541ab5e.zip
Handle assembler warnings properly
-rw-r--r--src/librustc_codegen_llvm/back/write.rs22
-rw-r--r--src/librustc_codegen_llvm/llvm/diagnostic.rs12
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs13
-rw-r--r--src/librustc_codegen_ssa/back/write.rs20
-rw-r--r--src/librustc_errors/lib.rs5
-rw-r--r--src/librustc_session/session.rs3
-rw-r--r--src/rustllvm/RustWrapper.cpp47
-rw-r--r--src/test/ui/asm/srcloc.rs3
-rw-r--r--src/test/ui/asm/srcloc.stderr14
9 files changed, 124 insertions, 15 deletions
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 02a9294930d..26f5334668b 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -16,7 +16,7 @@ use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, Mo
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
 use rustc_data_structures::small_c_str::SmallCStr;
-use rustc_errors::{FatalError, Handler};
+use rustc_errors::{FatalError, Handler, Level};
 use rustc_fs_util::{link_or_copy, path_to_c_string};
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_middle::bug;
@@ -242,6 +242,7 @@ impl<'a> Drop for DiagnosticHandlers<'a> {
 fn report_inline_asm(
     cgcx: &CodegenContext<LlvmCodegenBackend>,
     msg: String,
+    level: llvm::DiagnosticLevel,
     mut cookie: c_uint,
     source: Option<(String, Vec<InnerSpan>)>,
 ) {
@@ -251,7 +252,12 @@ fn report_inline_asm(
     if matches!(cgcx.lto, Lto::Fat | Lto::Thin) {
         cookie = 0;
     }
-    cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, source);
+    let level = match level {
+        llvm::DiagnosticLevel::Error => Level::Error,
+        llvm::DiagnosticLevel::Warning => Level::Warning,
+        llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note,
+    };
+    cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, level, source);
 }
 
 unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void, cookie: c_uint) {
@@ -264,6 +270,7 @@ unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void
     // diagnostics.
     let mut have_source = false;
     let mut buffer = String::new();
+    let mut level = llvm::DiagnosticLevel::Error;
     let mut loc = 0;
     let mut ranges = [0; 8];
     let mut num_ranges = ranges.len() / 2;
@@ -273,6 +280,7 @@ unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void
                 diag,
                 msg,
                 buffer,
+                &mut level,
                 &mut loc,
                 ranges.as_mut_ptr(),
                 &mut num_ranges,
@@ -290,7 +298,7 @@ unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void
         (buffer, spans)
     });
 
-    report_inline_asm(cgcx, msg, cookie, source);
+    report_inline_asm(cgcx, msg, level, cookie, source);
 }
 
 unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {
@@ -301,7 +309,13 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
 
     match llvm::diagnostic::Diagnostic::unpack(info) {
         llvm::diagnostic::InlineAsm(inline) => {
-            report_inline_asm(cgcx, llvm::twine_to_string(inline.message), inline.cookie, None);
+            report_inline_asm(
+                cgcx,
+                llvm::twine_to_string(inline.message),
+                inline.level,
+                inline.cookie,
+                None,
+            );
         }
 
         llvm::diagnostic::Optimization(opt) => {
diff --git a/src/librustc_codegen_llvm/llvm/diagnostic.rs b/src/librustc_codegen_llvm/llvm/diagnostic.rs
index 4347cd06532..47f5c94e70c 100644
--- a/src/librustc_codegen_llvm/llvm/diagnostic.rs
+++ b/src/librustc_codegen_llvm/llvm/diagnostic.rs
@@ -88,6 +88,7 @@ impl OptimizationDiagnostic<'ll> {
 
 #[derive(Copy, Clone)]
 pub struct InlineAsmDiagnostic<'ll> {
+    pub level: super::DiagnosticLevel,
     pub cookie: c_uint,
     pub message: &'ll Twine,
     pub instruction: Option<&'ll Value>,
@@ -98,10 +99,17 @@ impl InlineAsmDiagnostic<'ll> {
         let mut cookie = 0;
         let mut message = None;
         let mut instruction = None;
+        let mut level = super::DiagnosticLevel::Error;
 
-        super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut cookie, &mut message, &mut instruction);
+        super::LLVMRustUnpackInlineAsmDiagnostic(
+            di,
+            &mut level,
+            &mut cookie,
+            &mut message,
+            &mut instruction,
+        );
 
-        InlineAsmDiagnostic { cookie, message: message.unwrap(), instruction }
+        InlineAsmDiagnostic { level, cookie, message: message.unwrap(), instruction }
     }
 }
 
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 759c2bf1b85..3c981af73ab 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -489,6 +489,17 @@ pub enum DiagnosticKind {
     Linker,
 }
 
+/// LLVMRustDiagnosticLevel
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[allow(dead_code)] // Variants constructed by C++.
+pub enum DiagnosticLevel {
+    Error,
+    Warning,
+    Note,
+    Remark,
+}
+
 /// LLVMRustArchiveKind
 #[derive(Copy, Clone)]
 #[repr(C)]
@@ -2054,6 +2065,7 @@ extern "C" {
 
     pub fn LLVMRustUnpackInlineAsmDiagnostic(
         DI: &'a DiagnosticInfo,
+        level_out: &mut DiagnosticLevel,
         cookie_out: &mut c_uint,
         message_out: &mut Option<&'a Twine>,
         instruction_out: &mut Option<&'a Value>,
@@ -2074,6 +2086,7 @@ extern "C" {
         d: &SMDiagnostic,
         message_out: &RustString,
         buffer_out: &RustString,
+        level_out: &mut DiagnosticLevel,
         loc_out: &mut c_uint,
         ranges_out: *mut c_uint,
         num_ranges: &mut usize,
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index cb5c95c11fa..c118e5ebdb7 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -1551,7 +1551,7 @@ fn spawn_work<B: ExtraBackendMethods>(cgcx: CodegenContext<B>, work: WorkItem<B>
 
 enum SharedEmitterMessage {
     Diagnostic(Diagnostic),
-    InlineAsmError(u32, String, Option<(String, Vec<InnerSpan>)>),
+    InlineAsmError(u32, String, Level, Option<(String, Vec<InnerSpan>)>),
     AbortIfErrors,
     Fatal(String),
 }
@@ -1576,9 +1576,10 @@ impl SharedEmitter {
         &self,
         cookie: u32,
         msg: String,
+        level: Level,
         source: Option<(String, Vec<InnerSpan>)>,
     ) {
-        drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg, source)));
+        drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)));
     }
 
     pub fn fatal(&self, msg: &str) {
@@ -1631,16 +1632,21 @@ impl SharedEmitterMain {
                     }
                     handler.emit_diagnostic(&d);
                 }
-                Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, source)) => {
+                Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
                     let msg = msg.strip_prefix("error: ").unwrap_or(&msg);
 
+                    let mut err = match level {
+                        Level::Error => sess.struct_err(&msg),
+                        Level::Warning => sess.struct_warn(&msg),
+                        Level::Note => sess.struct_note_without_error(&msg),
+                        _ => bug!("Invalid inline asm diagnostic level"),
+                    };
+
                     // If the cookie is 0 then we don't have span information.
-                    let mut err = if cookie == 0 {
-                        sess.struct_err(&msg)
-                    } else {
+                    if cookie != 0 {
                         let pos = BytePos::from_u32(cookie);
                         let span = Span::with_root_ctxt(pos, pos);
-                        sess.struct_span_err(span, &msg)
+                        err.set_span(span);
                     };
 
                     // Point to the generated assembly if it is available.
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index e4a560e434a..7261c638ce0 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -581,6 +581,11 @@ impl Handler {
         DiagnosticBuilder::new(self, Level::Help, msg)
     }
 
+    /// Construct a builder at the `Note` level with the `msg`.
+    pub fn struct_note_without_error(&self, msg: &str) -> DiagnosticBuilder<'_> {
+        DiagnosticBuilder::new(self, Level::Note, msg)
+    }
+
     pub fn span_fatal(&self, span: impl Into<MultiSpan>, msg: &str) -> FatalError {
         self.emit_diag_at_span(Diagnostic::new(Fatal, msg), span);
         FatalError
diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs
index 048033846a1..06d7d4f14d8 100644
--- a/src/librustc_session/session.rs
+++ b/src/librustc_session/session.rs
@@ -441,6 +441,9 @@ impl Session {
     pub fn span_note_without_error<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.diagnostic().span_note_without_error(sp, msg)
     }
+    pub fn struct_note_without_error(&self, msg: &str) -> DiagnosticBuilder<'_> {
+        self.diagnostic().struct_note_without_error(msg)
+    }
 
     pub fn diagnostic(&self) -> &rustc_errors::Handler {
         &self.parse_sess.span_diagnostic
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 6fac2662506..4704622922a 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -1094,8 +1094,17 @@ extern "C" void LLVMRustUnpackOptimizationDiagnostic(
   MessageOS << Opt->getMsg();
 }
 
+enum class LLVMRustDiagnosticLevel {
+    Error,
+    Warning,
+    Note,
+    Remark,
+};
+
 extern "C" void
-LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI, unsigned *CookieOut,
+LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
+                                  LLVMRustDiagnosticLevel *LevelOut,
+                                  unsigned *CookieOut,
                                   LLVMTwineRef *MessageOut,
                                   LLVMValueRef *InstructionOut) {
   // Undefined to call this not on an inline assembly diagnostic!
@@ -1105,6 +1114,23 @@ LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI, unsigned *CookieOut,
   *CookieOut = IA->getLocCookie();
   *MessageOut = wrap(&IA->getMsgStr());
   *InstructionOut = wrap(IA->getInstruction());
+
+  switch (IA->getSeverity()) {
+    case DS_Error:
+      *LevelOut = LLVMRustDiagnosticLevel::Error;
+      break;
+    case DS_Warning:
+      *LevelOut = LLVMRustDiagnosticLevel::Warning;
+      break;
+    case DS_Note:
+      *LevelOut = LLVMRustDiagnosticLevel::Note;
+      break;
+    case DS_Remark:
+      *LevelOut = LLVMRustDiagnosticLevel::Remark;
+      break;
+    default:
+      report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
+  }
 }
 
 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
@@ -1166,6 +1192,7 @@ extern "C" LLVMRustDiagnosticKind
 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
   return toRust((DiagnosticKind)unwrap(DI)->getKind());
 }
+
 // This is kept distinct from LLVMGetTypeKind, because when
 // a new type kind is added, the Rust-side enum must be
 // updated or UB will result.
@@ -1219,6 +1246,7 @@ extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
 extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
                                            RustStringRef MessageOut,
                                            RustStringRef BufferOut,
+                                           LLVMRustDiagnosticLevel* LevelOut,
                                            unsigned* LocOut,
                                            unsigned* RangesOut,
                                            size_t* NumRanges) {
@@ -1226,6 +1254,23 @@ extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
   RawRustStringOstream MessageOS(MessageOut);
   MessageOS << D.getMessage();
 
+  switch (D.getKind()) {
+    case SourceMgr::DK_Error:
+      *LevelOut = LLVMRustDiagnosticLevel::Error;
+      break;
+    case SourceMgr::DK_Warning:
+      *LevelOut = LLVMRustDiagnosticLevel::Warning;
+      break;
+    case SourceMgr::DK_Note:
+      *LevelOut = LLVMRustDiagnosticLevel::Note;
+      break;
+    case SourceMgr::DK_Remark:
+      *LevelOut = LLVMRustDiagnosticLevel::Remark;
+      break;
+    default:
+      report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
+  }
+
   if (D.getLoc() == SMLoc())
     return false;
 
diff --git a/src/test/ui/asm/srcloc.rs b/src/test/ui/asm/srcloc.rs
index 7af6f620a98..402adc50d5b 100644
--- a/src/test/ui/asm/srcloc.rs
+++ b/src/test/ui/asm/srcloc.rs
@@ -37,5 +37,8 @@ fn main() {
 
         asm!(concat!("invalid", "_", "instruction"));
         //~^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!("movaps %xmm3, (%esi, 2)", options(att_syntax));
+        //~^ WARN: scale factor without index register is ignored
     }
 }
diff --git a/src/test/ui/asm/srcloc.stderr b/src/test/ui/asm/srcloc.stderr
index 57a4fbb9742..d5d12b00481 100644
--- a/src/test/ui/asm/srcloc.stderr
+++ b/src/test/ui/asm/srcloc.stderr
@@ -70,5 +70,17 @@ note: instantiated into assembly here
 LL |     invalid_instruction
    |     ^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 6 previous errors
+warning: scale factor without index register is ignored
+  --> $DIR/srcloc.rs:41:15
+   |
+LL |         asm!("movaps %xmm3, (%esi, 2)", options(att_syntax));
+   |               ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:23
+   |
+LL |     movaps %xmm3, (%esi, 2)
+   |                          ^
+
+error: aborting due to 6 previous errors; 1 warning emitted