diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-05-06 13:30:04 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-06 13:30:04 +0200 |
| commit | 8172ada984b4fa18967f08ce8651f8a8ae817400 (patch) | |
| tree | 14c4d790371c227098381df1f875737ae9a8a2fb | |
| parent | 77004eafeaf8f579fdcd9a746ee59274a83b8ad7 (diff) | |
| parent | bba2a1e07179c59b422e60411813446606b1b7f3 (diff) | |
| download | rust-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.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_span/src/lib.rs | 22 |
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`. |
