Skip to content

Commit bba2a1e

Browse files
committed
Fix spans in LLVM-generated inline asm errors
Previously, incorrect spans were reported if inline assembly contained CRLF (Windows) line endings. Fixes #110885
1 parent af2c7e0 commit bba2a1e

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

compiler/rustc_codegen_ssa/src/back/write.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -1821,9 +1821,15 @@ impl SharedEmitterMain {
18211821
let source = sess
18221822
.source_map()
18231823
.new_source_file(FileName::inline_asm_source_code(&buffer), buffer);
1824-
let source_span = Span::with_root_ctxt(source.start_pos, source.end_pos);
1825-
let spans: Vec<_> =
1826-
spans.iter().map(|sp| source_span.from_inner(*sp)).collect();
1824+
let spans: Vec<_> = spans
1825+
.iter()
1826+
.map(|sp| {
1827+
Span::with_root_ctxt(
1828+
source.normalized_byte_pos(sp.start as u32),
1829+
source.normalized_byte_pos(sp.end as u32),
1830+
)
1831+
})
1832+
.collect();
18271833
err.span_note(spans, "instantiated into assembly here");
18281834
}
18291835

compiler/rustc_span/src/lib.rs

+22
Original file line numberDiff line numberDiff line change
@@ -1745,6 +1745,28 @@ impl SourceFile {
17451745
BytePos::from_u32(pos.0 - self.start_pos.0 + diff)
17461746
}
17471747

1748+
/// Calculates a normalized byte position from a byte offset relative to the
1749+
/// start of the file.
1750+
///
1751+
/// When we get an inline assembler error from LLVM during codegen, we
1752+
/// import the expanded assembly code as a new `SourceFile`, which can then
1753+
/// be used for error reporting with spans. However the byte offsets given
1754+
/// to us by LLVM are relative to the start of the original buffer, not the
1755+
/// normalized one. Hence we need to convert those offsets to the normalized
1756+
/// form when constructing spans.
1757+
pub fn normalized_byte_pos(&self, offset: u32) -> BytePos {
1758+
let diff = match self
1759+
.normalized_pos
1760+
.binary_search_by(|np| (np.pos.0 + np.diff).cmp(&(self.start_pos.0 + offset)))
1761+
{
1762+
Ok(i) => self.normalized_pos[i].diff,
1763+
Err(i) if i == 0 => 0,
1764+
Err(i) => self.normalized_pos[i - 1].diff,
1765+
};
1766+
1767+
BytePos::from_u32(self.start_pos.0 + offset - diff)
1768+
}
1769+
17481770
/// Converts an absolute `BytePos` to a `CharPos` relative to the `SourceFile`.
17491771
pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
17501772
// The number of extra bytes due to multibyte chars in the `SourceFile`.

0 commit comments

Comments
 (0)