Skip to content

Commit 484cb4e

Browse files
committed
Auto merge of #114332 - nbdd0121:riscv, r=compiler-errors
Fix ABI flags in RISC-V/LoongArch ELF file generated by rustc Fix #114153 It turns out the current way to set these flags are completely wrong. In LLVM the target ABI is used instead of target features to determine these flags. Not sure how to write a test though. Or maybe a test isn't necessary because this affects only those touching target json? r? `@Nilstrieb`
2 parents 82c5732 + 2f68d97 commit 484cb4e

File tree

5 files changed

+75
-70
lines changed

5 files changed

+75
-70
lines changed

compiler/rustc_codegen_ssa/src/back/metadata.rs

+21-17
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_metadata::fs::METADATA_FILENAME;
1616
use rustc_metadata::EncodedMetadata;
1717
use rustc_session::cstore::MetadataLoader;
1818
use rustc_session::Session;
19+
use rustc_span::sym;
1920
use rustc_target::abi::Endian;
2021
use rustc_target::spec::{ef_avr_arch, RelocModel, Target};
2122

@@ -272,35 +273,38 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
272273
Architecture::Riscv32 | Architecture::Riscv64 => {
273274
// Source: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/079772828bd10933d34121117a222b4cc0ee2200/riscv-elf.adoc
274275
let mut e_flags: u32 = 0x0;
275-
let features = &sess.target.options.features;
276+
276277
// Check if compressed is enabled
277-
if features.contains("+c") {
278+
// `unstable_target_features` is used here because "c" is gated behind riscv_target_feature.
279+
if sess.unstable_target_features.contains(&sym::c) {
278280
e_flags |= elf::EF_RISCV_RVC;
279281
}
280282

281-
// Select the appropriate floating-point ABI
282-
if features.contains("+d") {
283-
e_flags |= elf::EF_RISCV_FLOAT_ABI_DOUBLE;
284-
} else if features.contains("+f") {
285-
e_flags |= elf::EF_RISCV_FLOAT_ABI_SINGLE;
286-
} else {
287-
e_flags |= elf::EF_RISCV_FLOAT_ABI_SOFT;
283+
// Set the appropriate flag based on ABI
284+
// This needs to match LLVM `RISCVELFStreamer.cpp`
285+
match &*sess.target.llvm_abiname {
286+
"" | "ilp32" | "lp64" => (),
287+
"ilp32f" | "lp64f" => e_flags |= elf::EF_RISCV_FLOAT_ABI_SINGLE,
288+
"ilp32d" | "lp64d" => e_flags |= elf::EF_RISCV_FLOAT_ABI_DOUBLE,
289+
"ilp32e" => e_flags |= elf::EF_RISCV_RVE,
290+
_ => bug!("unknown RISC-V ABI name"),
288291
}
292+
289293
e_flags
290294
}
291295
Architecture::LoongArch64 => {
292296
// Source: https://github.com/loongson/la-abi-specs/blob/release/laelf.adoc#e_flags-identifies-abi-type-and-version
293297
let mut e_flags: u32 = elf::EF_LARCH_OBJABI_V1;
294-
let features = &sess.target.options.features;
295298

296-
// Select the appropriate floating-point ABI
297-
if features.contains("+d") {
298-
e_flags |= elf::EF_LARCH_ABI_DOUBLE_FLOAT;
299-
} else if features.contains("+f") {
300-
e_flags |= elf::EF_LARCH_ABI_SINGLE_FLOAT;
301-
} else {
302-
e_flags |= elf::EF_LARCH_ABI_SOFT_FLOAT;
299+
// Set the appropriate flag based on ABI
300+
// This needs to match LLVM `LoongArchELFStreamer.cpp`
301+
match &*sess.target.llvm_abiname {
302+
"ilp32s" | "lp64s" => e_flags |= elf::EF_LARCH_ABI_SOFT_FLOAT,
303+
"ilp32f" | "lp64f" => e_flags |= elf::EF_LARCH_ABI_SINGLE_FLOAT,
304+
"ilp32d" | "lp64d" => e_flags |= elf::EF_LARCH_ABI_DOUBLE_FLOAT,
305+
_ => bug!("unknown RISC-V ABI name"),
303306
}
307+
304308
e_flags
305309
}
306310
Architecture::Avr => {

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ symbols! {
445445
bridge,
446446
bswap,
447447
builtin_syntax,
448+
c,
448449
c_str,
449450
c_str_literals,
450451
c_unwind,

tests/ui/or-patterns/missing-bindings.stderr

+34-34
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ LL | let (A(A(..) | B(a), _) | B(A(a, _) | B(a))) = Y;
7979
| |
8080
| pattern doesn't bind `a`
8181

82+
error[E0408]: variable `c` is not bound in all patterns
83+
--> $DIR/missing-bindings.rs:45:12
84+
|
85+
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
86+
| ^^^^^^^ - variable not in all patterns
87+
| |
88+
| pattern doesn't bind `c`
89+
8290
error[E0408]: variable `a` is not bound in all patterns
8391
--> $DIR/missing-bindings.rs:45:22
8492
|
@@ -96,12 +104,12 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
96104
| variable not in all patterns
97105

98106
error[E0408]: variable `c` is not bound in all patterns
99-
--> $DIR/missing-bindings.rs:45:12
107+
--> $DIR/missing-bindings.rs:45:33
100108
|
101109
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
102-
| ^^^^^^^ - variable not in all patterns
103-
| |
104-
| pattern doesn't bind `c`
110+
| - ^^^^ pattern doesn't bind `c`
111+
| |
112+
| variable not in all patterns
105113

106114
error[E0408]: variable `d` is not bound in all patterns
107115
--> $DIR/missing-bindings.rs:45:33
@@ -135,14 +143,6 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
135143
| |
136144
| variable not in all patterns
137145

138-
error[E0408]: variable `c` is not bound in all patterns
139-
--> $DIR/missing-bindings.rs:45:33
140-
|
141-
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
142-
| - ^^^^ pattern doesn't bind `c`
143-
| |
144-
| variable not in all patterns
145-
146146
error[E0408]: variable `a` is not bound in all patterns
147147
--> $DIR/missing-bindings.rs:61:29
148148
|
@@ -185,6 +185,28 @@ LL | B(b),
185185
LL | B(_)
186186
| ^^^^ pattern doesn't bind `b`
187187

188+
error[E0408]: variable `c` is not bound in all patterns
189+
--> $DIR/missing-bindings.rs:57:13
190+
|
191+
LL | / V1(
192+
LL | |
193+
LL | |
194+
LL | | A(
195+
... |
196+
LL | | B(Ok(a) | Err(a))
197+
LL | | ) |
198+
| |_____________^ pattern doesn't bind `c`
199+
LL | / V2(
200+
LL | | A(
201+
LL | | A(_, a) |
202+
LL | | B(b),
203+
... |
204+
LL | |
205+
LL | | ) |
206+
| |_____________^ pattern doesn't bind `c`
207+
LL | V3(c),
208+
| - variable not in all patterns
209+
188210
error[E0408]: variable `a` is not bound in all patterns
189211
--> $DIR/missing-bindings.rs:76:13
190212
|
@@ -215,28 +237,6 @@ LL | B(b),
215237
LL | V3(c),
216238
| ^^^^^ pattern doesn't bind `b`
217239

218-
error[E0408]: variable `c` is not bound in all patterns
219-
--> $DIR/missing-bindings.rs:57:13
220-
|
221-
LL | / V1(
222-
LL | |
223-
LL | |
224-
LL | | A(
225-
... |
226-
LL | | B(Ok(a) | Err(a))
227-
LL | | ) |
228-
| |_____________^ pattern doesn't bind `c`
229-
LL | / V2(
230-
LL | | A(
231-
LL | | A(_, a) |
232-
LL | | B(b),
233-
... |
234-
LL | |
235-
LL | | ) |
236-
| |_____________^ pattern doesn't bind `c`
237-
LL | V3(c),
238-
| - variable not in all patterns
239-
240240
error: aborting due to 26 previous errors
241241

242242
For more information about this error, try `rustc --explain E0408`.

tests/ui/resolve/resolve-inconsistent-names.stderr

+9-9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ LL | a | b => {}
1414
| |
1515
| pattern doesn't bind `b`
1616

17+
error[E0408]: variable `c` is not bound in all patterns
18+
--> $DIR/resolve-inconsistent-names.rs:19:9
19+
|
20+
LL | (A, B) | (ref B, c) | (c, A) => ()
21+
| ^^^^^^ - - variable not in all patterns
22+
| | |
23+
| | variable not in all patterns
24+
| pattern doesn't bind `c`
25+
1726
error[E0408]: variable `A` is not bound in all patterns
1827
--> $DIR/resolve-inconsistent-names.rs:19:18
1928
|
@@ -37,15 +46,6 @@ LL | (A, B) | (ref B, c) | (c, A) => ()
3746
| | variable not in all patterns
3847
| variable not in all patterns
3948

40-
error[E0408]: variable `c` is not bound in all patterns
41-
--> $DIR/resolve-inconsistent-names.rs:19:9
42-
|
43-
LL | (A, B) | (ref B, c) | (c, A) => ()
44-
| ^^^^^^ - - variable not in all patterns
45-
| | |
46-
| | variable not in all patterns
47-
| pattern doesn't bind `c`
48-
4949
error[E0409]: variable `B` is bound inconsistently across alternatives separated by `|`
5050
--> $DIR/resolve-inconsistent-names.rs:19:23
5151
|

tests/ui/span/issue-39698.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
error[E0408]: variable `c` is not bound in all patterns
2+
--> $DIR/issue-39698.rs:10:9
3+
|
4+
LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
5+
| ^^^^^^^^^^^ ^^^^^^^^^^^ - ^^^^^^^^ pattern doesn't bind `c`
6+
| | | |
7+
| | | variable not in all patterns
8+
| | pattern doesn't bind `c`
9+
| pattern doesn't bind `c`
10+
111
error[E0408]: variable `d` is not bound in all patterns
212
--> $DIR/issue-39698.rs:10:37
313
|
@@ -28,16 +38,6 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
2838
| | variable not in all patterns
2939
| pattern doesn't bind `b`
3040

31-
error[E0408]: variable `c` is not bound in all patterns
32-
--> $DIR/issue-39698.rs:10:9
33-
|
34-
LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
35-
| ^^^^^^^^^^^ ^^^^^^^^^^^ - ^^^^^^^^ pattern doesn't bind `c`
36-
| | | |
37-
| | | variable not in all patterns
38-
| | pattern doesn't bind `c`
39-
| pattern doesn't bind `c`
40-
4141
error: aborting due to 4 previous errors
4242

4343
For more information about this error, try `rustc --explain E0408`.

0 commit comments

Comments
 (0)