about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-05-06 13:30:04 +0200
committerGitHub <noreply@github.com>2023-05-06 13:30:04 +0200
commit8172ada984b4fa18967f08ce8651f8a8ae817400 (patch)
tree14c4d790371c227098381df1f875737ae9a8a2fb
parent77004eafeaf8f579fdcd9a746ee59274a83b8ad7 (diff)
parentbba2a1e07179c59b422e60411813446606b1b7f3 (diff)
downloadrust-8172ada984b4fa18967f08ce8651f8a8ae817400.tar.gz
rust-8172ada984b4fa18967f08ce8651f8a8ae817400.zip
Rollup merge of #110985 - Amanieu:normalize_asm_spans, r=b-naber
Fix spans in LLVM-generated inline asm errors

Previously, incorrect spans were reported if inline assembly contained CRLF (Windows) line endings.

Fixes #110885
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs12
-rw-r--r--compiler/rustc_span/src/lib.rs22
2 files changed, 31 insertions, 3 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index c42d59bd51c..c323372bda4 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -1821,9 +1821,15 @@ impl SharedEmitterMain {
                         let source = sess
                             .source_map()
                             .new_source_file(FileName::inline_asm_source_code(&buffer), buffer);
-                        let source_span = Span::with_root_ctxt(source.start_pos, source.end_pos);
-                        let spans: Vec<_> =
-                            spans.iter().map(|sp| source_span.from_inner(*sp)).collect();
+                        let spans: Vec<_> = spans
+                            .iter()
+                            .map(|sp| {
+                                Span::with_root_ctxt(
+                                    source.normalized_byte_pos(sp.start as u32),
+                                    source.normalized_byte_pos(sp.end as u32),
+                                )
+                            })
+                            .collect();
                         err.span_note(spans, "instantiated into assembly here");
                     }
 
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 5654a3979a0..7bbab34c69a 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -1744,6 +1744,28 @@ impl SourceFile {
         BytePos::from_u32(pos.0 - self.start_pos.0 + diff)
     }
 
+    /// Calculates a normalized byte position from a byte offset relative to the
+    /// start of the file.
+    ///
+    /// When we get an inline assembler error from LLVM during codegen, we
+    /// import the expanded assembly code as a new `SourceFile`, which can then
+    /// be used for error reporting with spans. However the byte offsets given
+    /// to us by LLVM are relative to the start of the original buffer, not the
+    /// normalized one. Hence we need to convert those offsets to the normalized
+    /// form when constructing spans.
+    pub fn normalized_byte_pos(&self, offset: u32) -> BytePos {
+        let diff = match self
+            .normalized_pos
+            .binary_search_by(|np| (np.pos.0 + np.diff).cmp(&(self.start_pos.0 + offset)))
+        {
+            Ok(i) => self.normalized_pos[i].diff,
+            Err(i) if i == 0 => 0,
+            Err(i) => self.normalized_pos[i - 1].diff,
+        };
+
+        BytePos::from_u32(self.start_pos.0 + offset - diff)
+    }
+
     /// Converts an absolute `BytePos` to a `CharPos` relative to the `SourceFile`.
     pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
         // The number of extra bytes due to multibyte chars in the `SourceFile`.