Skip to content

Commit abef761

Browse files
committed
Pass end position of span through inline ASM cookie
1 parent 6b9676b commit abef761

24 files changed

+1565
-200
lines changed

Diff for: compiler/rustc_codegen_llvm/src/asm.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -487,14 +487,13 @@ pub(crate) fn inline_asm_call<'ll>(
487487
let key = "srcloc";
488488
let kind = llvm::LLVMGetMDKindIDInContext(
489489
bx.llcx,
490-
key.as_ptr() as *const c_char,
490+
key.as_ptr().cast::<c_char>(),
491491
key.len() as c_uint,
492492
);
493493

494-
// srcloc contains one integer for each line of assembly code.
495-
// Unfortunately this isn't enough to encode a full span so instead
496-
// we just encode the start position of each line.
497-
// FIXME: Figure out a way to pass the entire line spans.
494+
// `srcloc` contains one 64-bit integer for each line of assembly code,
495+
// where the lower 32 bits hold the lo byte position and the upper 32 bits
496+
// hold the hi byte position.
498497
let mut srcloc = vec![];
499498
if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
500499
// LLVM inserts an extra line to add the ".intel_syntax", so add
@@ -504,13 +503,13 @@ pub(crate) fn inline_asm_call<'ll>(
504503
// due to the asm template string coming from a macro. LLVM will
505504
// default to the first srcloc for lines that don't have an
506505
// associated srcloc.
507-
srcloc.push(llvm::LLVMValueAsMetadata(bx.const_i32(0)));
506+
srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0)));
508507
}
509-
srcloc.extend(
510-
line_spans
511-
.iter()
512-
.map(|span| llvm::LLVMValueAsMetadata(bx.const_i32(span.lo().to_u32() as i32))),
513-
);
508+
srcloc.extend(line_spans.iter().map(|span| {
509+
llvm::LLVMValueAsMetadata(bx.const_u64(
510+
u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32),
511+
))
512+
}));
514513
let md = llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len());
515514
let md = llvm::LLVMMetadataAsValue(&bx.llcx, md);
516515
llvm::LLVMSetMetadata(call, kind, md);

Diff for: compiler/rustc_codegen_llvm/src/back/write.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use rustc_session::Session;
2424
use rustc_session::config::{
2525
self, Lto, OutputType, Passes, RemapPathScopeComponents, SplitDwarfKind, SwitchWithOptPath,
2626
};
27-
use rustc_span::InnerSpan;
2827
use rustc_span::symbol::sym;
28+
use rustc_span::{BytePos, InnerSpan, Pos, SpanData, SyntaxContext};
2929
use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
3030
use tracing::debug;
3131

@@ -411,21 +411,32 @@ fn report_inline_asm(
411411
cgcx: &CodegenContext<LlvmCodegenBackend>,
412412
msg: String,
413413
level: llvm::DiagnosticLevel,
414-
mut cookie: u64,
414+
cookie: u64,
415415
source: Option<(String, Vec<InnerSpan>)>,
416416
) {
417417
// In LTO build we may get srcloc values from other crates which are invalid
418418
// since they use a different source map. To be safe we just suppress these
419419
// in LTO builds.
420-
if matches!(cgcx.lto, Lto::Fat | Lto::Thin) {
421-
cookie = 0;
422-
}
420+
let span = if cookie == 0 || matches!(cgcx.lto, Lto::Fat | Lto::Thin) {
421+
SpanData::default()
422+
} else {
423+
let lo = BytePos::from_u32(cookie as u32);
424+
let hi = BytePos::from_u32((cookie >> 32) as u32);
425+
SpanData {
426+
lo,
427+
// LLVM version < 19 silently truncates the cookie to 32 bits in some situations.
428+
hi: if hi.to_u32() != 0 { hi } else { lo },
429+
ctxt: SyntaxContext::root(),
430+
parent: None,
431+
}
432+
};
423433
let level = match level {
424434
llvm::DiagnosticLevel::Error => Level::Error,
425435
llvm::DiagnosticLevel::Warning => Level::Warning,
426436
llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note,
427437
};
428-
cgcx.diag_emitter.inline_asm_error(cookie.try_into().unwrap(), msg, level, source);
438+
let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
439+
cgcx.diag_emitter.inline_asm_error(span, msg, level, source);
429440
}
430441

431442
unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {

Diff for: compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl InlineAsmDiagnostic {
151151
unsafe { SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie)) };
152152
InlineAsmDiagnostic {
153153
level: smdiag.level,
154-
cookie: cookie.into(),
154+
cookie,
155155
message: smdiag.message,
156156
source: smdiag.source,
157157
}

Diff for: compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2271,7 +2271,7 @@ unsafe extern "C" {
22712271

22722272
pub fn LLVMRustGetSMDiagnostic<'a>(
22732273
DI: &'a DiagnosticInfo,
2274-
cookie_out: &mut c_uint,
2274+
cookie_out: &mut u64,
22752275
) -> &'a SMDiagnostic;
22762276

22772277
#[allow(improper_ctypes)]

Diff for: compiler/rustc_codegen_ssa/src/back/write.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use rustc_session::config::{
3434
};
3535
use rustc_span::source_map::SourceMap;
3636
use rustc_span::symbol::sym;
37-
use rustc_span::{BytePos, FileName, InnerSpan, Pos, Span};
37+
use rustc_span::{FileName, InnerSpan, Span, SpanData};
3838
use rustc_target::spec::{MergeFunctions, SanitizerSet};
3939
use tracing::debug;
4040

@@ -1852,7 +1852,7 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
18521852

18531853
enum SharedEmitterMessage {
18541854
Diagnostic(Diagnostic),
1855-
InlineAsmError(u32, String, Level, Option<(String, Vec<InnerSpan>)>),
1855+
InlineAsmError(SpanData, String, Level, Option<(String, Vec<InnerSpan>)>),
18561856
Fatal(String),
18571857
}
18581858

@@ -1874,12 +1874,12 @@ impl SharedEmitter {
18741874

18751875
pub fn inline_asm_error(
18761876
&self,
1877-
cookie: u32,
1877+
span: SpanData,
18781878
msg: String,
18791879
level: Level,
18801880
source: Option<(String, Vec<InnerSpan>)>,
18811881
) {
1882-
drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)));
1882+
drop(self.sender.send(SharedEmitterMessage::InlineAsmError(span, msg, level, source)));
18831883
}
18841884

18851885
fn fatal(&self, msg: &str) {
@@ -1964,17 +1964,12 @@ impl SharedEmitterMain {
19641964
dcx.emit_diagnostic(d);
19651965
sess.dcx().abort_if_errors();
19661966
}
1967-
Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
1967+
Ok(SharedEmitterMessage::InlineAsmError(span, msg, level, source)) => {
19681968
assert_matches!(level, Level::Error | Level::Warning | Level::Note);
1969-
let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
19701969
let mut err = Diag::<()>::new(sess.dcx(), level, msg);
1971-
1972-
// If the cookie is 0 then we don't have span information.
1973-
if cookie != 0 {
1974-
let pos = BytePos::from_u32(cookie);
1975-
let span = Span::with_root_ctxt(pos, pos);
1976-
err.span(span);
1977-
};
1970+
if !span.is_dummy() {
1971+
err.span(span.span());
1972+
}
19781973

19791974
// Point to the generated assembly if it is available.
19801975
if let Some((buffer, spans)) = source {

Diff for: compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1445,7 +1445,7 @@ extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
14451445
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
14461446

14471447
extern "C" LLVMSMDiagnosticRef LLVMRustGetSMDiagnostic(LLVMDiagnosticInfoRef DI,
1448-
unsigned *Cookie) {
1448+
uint64_t *Cookie) {
14491449
llvm::DiagnosticInfoSrcMgr *SM =
14501450
static_cast<llvm::DiagnosticInfoSrcMgr *>(unwrap(DI));
14511451
*Cookie = SM->getLocCookie();

Diff for: compiler/rustc_span/src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,12 @@ impl SpanData {
521521
}
522522
}
523523

524+
impl Default for SpanData {
525+
fn default() -> Self {
526+
Self { lo: BytePos(0), hi: BytePos(0), ctxt: SyntaxContext::root(), parent: None }
527+
}
528+
}
529+
524530
// The interner is pointed to by a thread local value which is only set on the main thread
525531
// with parallelization is disabled. So we don't allow `Span` to transfer between threads
526532
// to avoid panics and other errors, even though it would be memory safe to do so.

Diff for: tests/ui/abi/riscv32e-registers.riscv32e.stderr

+32-32
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: invalid operand for instruction
2-
--> $DIR/riscv32e-registers.rs:43:11
2+
--> $DIR/riscv32e-registers.rs:55:11
33
|
44
LL | asm!("li x16, 0");
5-
| ^
5+
| ^^^^^^^^^
66
|
77
note: instantiated into assembly here
88
--> <inline asm>:1:5
@@ -11,10 +11,10 @@ LL | li x16, 0
1111
| ^
1212

1313
error: invalid operand for instruction
14-
--> $DIR/riscv32e-registers.rs:46:11
14+
--> $DIR/riscv32e-registers.rs:58:11
1515
|
1616
LL | asm!("li x17, 0");
17-
| ^
17+
| ^^^^^^^^^
1818
|
1919
note: instantiated into assembly here
2020
--> <inline asm>:1:5
@@ -23,10 +23,10 @@ LL | li x17, 0
2323
| ^
2424

2525
error: invalid operand for instruction
26-
--> $DIR/riscv32e-registers.rs:49:11
26+
--> $DIR/riscv32e-registers.rs:61:11
2727
|
2828
LL | asm!("li x18, 0");
29-
| ^
29+
| ^^^^^^^^^
3030
|
3131
note: instantiated into assembly here
3232
--> <inline asm>:1:5
@@ -35,10 +35,10 @@ LL | li x18, 0
3535
| ^
3636

3737
error: invalid operand for instruction
38-
--> $DIR/riscv32e-registers.rs:52:11
38+
--> $DIR/riscv32e-registers.rs:64:11
3939
|
4040
LL | asm!("li x19, 0");
41-
| ^
41+
| ^^^^^^^^^
4242
|
4343
note: instantiated into assembly here
4444
--> <inline asm>:1:5
@@ -47,10 +47,10 @@ LL | li x19, 0
4747
| ^
4848

4949
error: invalid operand for instruction
50-
--> $DIR/riscv32e-registers.rs:55:11
50+
--> $DIR/riscv32e-registers.rs:67:11
5151
|
5252
LL | asm!("li x20, 0");
53-
| ^
53+
| ^^^^^^^^^
5454
|
5555
note: instantiated into assembly here
5656
--> <inline asm>:1:5
@@ -59,10 +59,10 @@ LL | li x20, 0
5959
| ^
6060

6161
error: invalid operand for instruction
62-
--> $DIR/riscv32e-registers.rs:58:11
62+
--> $DIR/riscv32e-registers.rs:70:11
6363
|
6464
LL | asm!("li x21, 0");
65-
| ^
65+
| ^^^^^^^^^
6666
|
6767
note: instantiated into assembly here
6868
--> <inline asm>:1:5
@@ -71,10 +71,10 @@ LL | li x21, 0
7171
| ^
7272

7373
error: invalid operand for instruction
74-
--> $DIR/riscv32e-registers.rs:61:11
74+
--> $DIR/riscv32e-registers.rs:73:11
7575
|
7676
LL | asm!("li x22, 0");
77-
| ^
77+
| ^^^^^^^^^
7878
|
7979
note: instantiated into assembly here
8080
--> <inline asm>:1:5
@@ -83,10 +83,10 @@ LL | li x22, 0
8383
| ^
8484

8585
error: invalid operand for instruction
86-
--> $DIR/riscv32e-registers.rs:64:11
86+
--> $DIR/riscv32e-registers.rs:76:11
8787
|
8888
LL | asm!("li x23, 0");
89-
| ^
89+
| ^^^^^^^^^
9090
|
9191
note: instantiated into assembly here
9292
--> <inline asm>:1:5
@@ -95,10 +95,10 @@ LL | li x23, 0
9595
| ^
9696

9797
error: invalid operand for instruction
98-
--> $DIR/riscv32e-registers.rs:67:11
98+
--> $DIR/riscv32e-registers.rs:79:11
9999
|
100100
LL | asm!("li x24, 0");
101-
| ^
101+
| ^^^^^^^^^
102102
|
103103
note: instantiated into assembly here
104104
--> <inline asm>:1:5
@@ -107,10 +107,10 @@ LL | li x24, 0
107107
| ^
108108

109109
error: invalid operand for instruction
110-
--> $DIR/riscv32e-registers.rs:70:11
110+
--> $DIR/riscv32e-registers.rs:82:11
111111
|
112112
LL | asm!("li x25, 0");
113-
| ^
113+
| ^^^^^^^^^
114114
|
115115
note: instantiated into assembly here
116116
--> <inline asm>:1:5
@@ -119,10 +119,10 @@ LL | li x25, 0
119119
| ^
120120

121121
error: invalid operand for instruction
122-
--> $DIR/riscv32e-registers.rs:73:11
122+
--> $DIR/riscv32e-registers.rs:85:11
123123
|
124124
LL | asm!("li x26, 0");
125-
| ^
125+
| ^^^^^^^^^
126126
|
127127
note: instantiated into assembly here
128128
--> <inline asm>:1:5
@@ -131,10 +131,10 @@ LL | li x26, 0
131131
| ^
132132

133133
error: invalid operand for instruction
134-
--> $DIR/riscv32e-registers.rs:76:11
134+
--> $DIR/riscv32e-registers.rs:88:11
135135
|
136136
LL | asm!("li x27, 0");
137-
| ^
137+
| ^^^^^^^^^
138138
|
139139
note: instantiated into assembly here
140140
--> <inline asm>:1:5
@@ -143,10 +143,10 @@ LL | li x27, 0
143143
| ^
144144

145145
error: invalid operand for instruction
146-
--> $DIR/riscv32e-registers.rs:79:11
146+
--> $DIR/riscv32e-registers.rs:91:11
147147
|
148148
LL | asm!("li x28, 0");
149-
| ^
149+
| ^^^^^^^^^
150150
|
151151
note: instantiated into assembly here
152152
--> <inline asm>:1:5
@@ -155,10 +155,10 @@ LL | li x28, 0
155155
| ^
156156

157157
error: invalid operand for instruction
158-
--> $DIR/riscv32e-registers.rs:82:11
158+
--> $DIR/riscv32e-registers.rs:94:11
159159
|
160160
LL | asm!("li x29, 0");
161-
| ^
161+
| ^^^^^^^^^
162162
|
163163
note: instantiated into assembly here
164164
--> <inline asm>:1:5
@@ -167,10 +167,10 @@ LL | li x29, 0
167167
| ^
168168

169169
error: invalid operand for instruction
170-
--> $DIR/riscv32e-registers.rs:85:11
170+
--> $DIR/riscv32e-registers.rs:97:11
171171
|
172172
LL | asm!("li x30, 0");
173-
| ^
173+
| ^^^^^^^^^
174174
|
175175
note: instantiated into assembly here
176176
--> <inline asm>:1:5
@@ -179,10 +179,10 @@ LL | li x30, 0
179179
| ^
180180

181181
error: invalid operand for instruction
182-
--> $DIR/riscv32e-registers.rs:88:11
182+
--> $DIR/riscv32e-registers.rs:100:11
183183
|
184184
LL | asm!("li x31, 0");
185-
| ^
185+
| ^^^^^^^^^
186186
|
187187
note: instantiated into assembly here
188188
--> <inline asm>:1:5

0 commit comments

Comments
 (0)