summary refs log tree commit diff
path: root/src/test/ui
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2020-05-30 23:08:44 +0200
committerGitHub <noreply@github.com>2020-05-30 23:08:44 +0200
commitfadfcb644e3e549b5b080260d4ca4ea2696e7007 (patch)
tree11b724345164340def6c91133e43f1a2b21659a4 /src/test/ui
parentf1661d23e386ecd2d2ebb7990fa4cb459b2896f6 (diff)
parentfc497f79b3a60e23da08680d66e6cfc00a716bcc (diff)
downloadrust-fadfcb644e3e549b5b080260d4ca4ea2696e7007.tar.gz
rust-fadfcb644e3e549b5b080260d4ca4ea2696e7007.zip
Rollup merge of #72625 - Amanieu:asm-srcloc, r=petrochenkov
Improve inline asm error diagnostics

Previously we were just using the raw LLVM error output (with line, caret, etc) as the diagnostic message, which ends up looking rather out of place with our existing diagnostics.

The new diagnostics properly format the diagnostics and also take advantage of LLVM's per-line `srcloc` attribute to map an error in inline assembly directly to the relevant line of source code.

Incidentally also fixes #71639 by disabling `srcloc` metadata during LTO builds since we don't know what crate it might have come from. We can only resolve `srcloc`s from the currently crate since it indexes into the source map for the current crate.

Fixes #72664
Fixes #71639

r? @petrochenkov

### Old style

```rust
#![feature(llvm_asm)]

fn main() {
    unsafe {
        let _x: i32;
        llvm_asm!(
            "mov $0, $1
             invalid_instruction $0, $1
             mov $0, $1"
             : "=&r" (_x)
             : "r" (0)
             :: "intel"
        );
    }
}
```

```
error: <inline asm>:3:14: error: invalid instruction mnemonic 'invalid_instruction'
             invalid_instruction ecx, eax
             ^~~~~~~~~~~~~~~~~~~

  --> src/main.rs:6:9
   |
6  | /         llvm_asm!(
7  | |             "mov $0, $1
8  | |              invalid_instruction $0, $1
9  | |              mov $0, $1"
...  |
12 | |              :: "intel"
13 | |         );
   | |__________^
```

### New style

```rust
#![feature(asm)]

fn main() {
    unsafe {
        asm!(
            "mov {0}, {1}
             invalid_instruction {0}, {1}
             mov {0}, {1}",
            out(reg) _,
            in(reg) 0i64,
        );
    }
}
```

```
error: invalid instruction mnemonic 'invalid_instruction'
 --> test.rs:7:14
  |
7 |              invalid_instruction {0}, {1}
  |              ^
  |
note: instantiated into assembly here
 --> <inline asm>:3:14
  |
3 |              invalid_instruction rax, rcx
  |              ^^^^^^^^^^^^^^^^^^^
```
Diffstat (limited to 'src/test/ui')
-rw-r--r--src/test/ui/asm/srcloc.rs41
-rw-r--r--src/test/ui/asm/srcloc.stderr74
-rw-r--r--src/test/ui/issues/issue-23458.stderr15
-rw-r--r--src/test/ui/llvm-asm/issue-69092.rs2
-rw-r--r--src/test/ui/llvm-asm/issue-69092.stderr13
5 files changed, 133 insertions, 12 deletions
diff --git a/src/test/ui/asm/srcloc.rs b/src/test/ui/asm/srcloc.rs
new file mode 100644
index 00000000000..7af6f620a98
--- /dev/null
+++ b/src/test/ui/asm/srcloc.rs
@@ -0,0 +1,41 @@
+// no-system-llvm
+// only-x86_64
+// build-fail
+
+#![feature(asm)]
+
+// Checks that inline asm errors are mapped to the correct line in the source code.
+
+fn main() {
+    unsafe {
+        asm!("invalid_instruction");
+        //~^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!("
+            invalid_instruction
+        ");
+        //~^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!(r#"
+            invalid_instruction
+        "#);
+        //~^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!("
+            mov eax, eax
+            invalid_instruction
+            mov eax, eax
+        ");
+        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!(r#"
+            mov eax, eax
+            invalid_instruction
+            mov eax, eax
+        "#);
+        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!(concat!("invalid", "_", "instruction"));
+        //~^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+    }
+}
diff --git a/src/test/ui/asm/srcloc.stderr b/src/test/ui/asm/srcloc.stderr
new file mode 100644
index 00000000000..57a4fbb9742
--- /dev/null
+++ b/src/test/ui/asm/srcloc.stderr
@@ -0,0 +1,74 @@
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:11:15
+   |
+LL |         asm!("invalid_instruction");
+   |               ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:15:13
+   |
+LL |             invalid_instruction
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:20:13
+   |
+LL |             invalid_instruction
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:26:13
+   |
+LL |             invalid_instruction
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:33:13
+   |
+LL |             invalid_instruction
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:38:14
+   |
+LL |         asm!(concat!("invalid", "_", "instruction"));
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/issues/issue-23458.stderr b/src/test/ui/issues/issue-23458.stderr
index 81f06e63975..a6500b9bb4c 100644
--- a/src/test/ui/issues/issue-23458.stderr
+++ b/src/test/ui/issues/issue-23458.stderr
@@ -2,16 +2,19 @@ error: invalid operand in inline asm: 'int $3'
   --> $DIR/issue-23458.rs:8:9
    |
 LL |         llvm_asm!("int $3");
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-error: <inline asm>:1:2: error: too few operands for instruction
-        int 
-        ^
+   |         ^
 
+error: too few operands for instruction
   --> $DIR/issue-23458.rs:8:9
    |
 LL |         llvm_asm!("int $3");
-   |         ^^^^^^^^^^^^^^^^^^^^
+   |         ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     int 
+   |     ^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/llvm-asm/issue-69092.rs b/src/test/ui/llvm-asm/issue-69092.rs
index ecce7bfdf5b..96c019b760e 100644
--- a/src/test/ui/llvm-asm/issue-69092.rs
+++ b/src/test/ui/llvm-asm/issue-69092.rs
@@ -6,5 +6,5 @@
 
 fn main() {
     unsafe { llvm_asm!(".ascii \"Xen\0\""); }
-    //~^ ERROR: <inline asm>:1:9: error: expected string in '.ascii' directive
+    //~^ ERROR: expected string in '.ascii' directive
 }
diff --git a/src/test/ui/llvm-asm/issue-69092.stderr b/src/test/ui/llvm-asm/issue-69092.stderr
index 35f77edc3c4..2ca86cf7c1b 100644
--- a/src/test/ui/llvm-asm/issue-69092.stderr
+++ b/src/test/ui/llvm-asm/issue-69092.stderr
@@ -1,11 +1,14 @@
-error: <inline asm>:1:9: error: expected string in '.ascii' directive
-        .ascii "Xen
-               ^
-
+error: expected string in '.ascii' directive
   --> $DIR/issue-69092.rs:8:14
    |
 LL |     unsafe { llvm_asm!(".ascii \"Xen\0\""); }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:9
+   |
+LL |     .ascii "Xen
+   |            ^
 
 error: aborting due to previous error