about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-08-20 04:38:08 +0000
committerbors <bors@rust-lang.org>2023-08-20 04:38:08 +0000
commit484cb4e78d5c7ec259b7d7540fbb18850ae7a6ba (patch)
tree6d2c4385b511cbb699a8174522f857e9f37caec6
parent82c5732b9ab4473c65d426866e67e8fdb23243fb (diff)
parent2f68d97b647807738b8597b8a9d156642285db47 (diff)
downloadrust-484cb4e78d5c7ec259b7d7540fbb18850ae7a6ba.tar.gz
rust-484cb4e78d5c7ec259b7d7540fbb18850ae7a6ba.zip
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`
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs38
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--tests/ui/or-patterns/missing-bindings.stderr68
-rw-r--r--tests/ui/resolve/resolve-inconsistent-names.stderr18
-rw-r--r--tests/ui/span/issue-39698.stderr20
5 files changed, 75 insertions, 70 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 0be84c9fa83..4c854740753 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -16,6 +16,7 @@ use rustc_metadata::fs::METADATA_FILENAME;
 use rustc_metadata::EncodedMetadata;
 use rustc_session::cstore::MetadataLoader;
 use rustc_session::Session;
+use rustc_span::sym;
 use rustc_target::abi::Endian;
 use rustc_target::spec::{ef_avr_arch, RelocModel, Target};
 
@@ -272,35 +273,38 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
         Architecture::Riscv32 | Architecture::Riscv64 => {
             // Source: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/079772828bd10933d34121117a222b4cc0ee2200/riscv-elf.adoc
             let mut e_flags: u32 = 0x0;
-            let features = &sess.target.options.features;
+
             // Check if compressed is enabled
-            if features.contains("+c") {
+            // `unstable_target_features` is used here because "c" is gated behind riscv_target_feature.
+            if sess.unstable_target_features.contains(&sym::c) {
                 e_flags |= elf::EF_RISCV_RVC;
             }
 
-            // Select the appropriate floating-point ABI
-            if features.contains("+d") {
-                e_flags |= elf::EF_RISCV_FLOAT_ABI_DOUBLE;
-            } else if features.contains("+f") {
-                e_flags |= elf::EF_RISCV_FLOAT_ABI_SINGLE;
-            } else {
-                e_flags |= elf::EF_RISCV_FLOAT_ABI_SOFT;
+            // Set the appropriate flag based on ABI
+            // This needs to match LLVM `RISCVELFStreamer.cpp`
+            match &*sess.target.llvm_abiname {
+                "" | "ilp32" | "lp64" => (),
+                "ilp32f" | "lp64f" => e_flags |= elf::EF_RISCV_FLOAT_ABI_SINGLE,
+                "ilp32d" | "lp64d" => e_flags |= elf::EF_RISCV_FLOAT_ABI_DOUBLE,
+                "ilp32e" => e_flags |= elf::EF_RISCV_RVE,
+                _ => bug!("unknown RISC-V ABI name"),
             }
+
             e_flags
         }
         Architecture::LoongArch64 => {
             // Source: https://github.com/loongson/la-abi-specs/blob/release/laelf.adoc#e_flags-identifies-abi-type-and-version
             let mut e_flags: u32 = elf::EF_LARCH_OBJABI_V1;
-            let features = &sess.target.options.features;
 
-            // Select the appropriate floating-point ABI
-            if features.contains("+d") {
-                e_flags |= elf::EF_LARCH_ABI_DOUBLE_FLOAT;
-            } else if features.contains("+f") {
-                e_flags |= elf::EF_LARCH_ABI_SINGLE_FLOAT;
-            } else {
-                e_flags |= elf::EF_LARCH_ABI_SOFT_FLOAT;
+            // Set the appropriate flag based on ABI
+            // This needs to match LLVM `LoongArchELFStreamer.cpp`
+            match &*sess.target.llvm_abiname {
+                "ilp32s" | "lp64s" => e_flags |= elf::EF_LARCH_ABI_SOFT_FLOAT,
+                "ilp32f" | "lp64f" => e_flags |= elf::EF_LARCH_ABI_SINGLE_FLOAT,
+                "ilp32d" | "lp64d" => e_flags |= elf::EF_LARCH_ABI_DOUBLE_FLOAT,
+                _ => bug!("unknown RISC-V ABI name"),
             }
+
             e_flags
         }
         Architecture::Avr => {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index e511898513a..28a2dfebcfe 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -445,6 +445,7 @@ symbols! {
         bridge,
         bswap,
         builtin_syntax,
+        c,
         c_str,
         c_str_literals,
         c_unwind,
diff --git a/tests/ui/or-patterns/missing-bindings.stderr b/tests/ui/or-patterns/missing-bindings.stderr
index 8fafa275b5c..4457b7893d5 100644
--- a/tests/ui/or-patterns/missing-bindings.stderr
+++ b/tests/ui/or-patterns/missing-bindings.stderr
@@ -79,6 +79,14 @@ LL |     let (A(A(..) | B(a), _) | B(A(a, _) | B(a))) = Y;
    |            |
    |            pattern doesn't bind `a`
 
+error[E0408]: variable `c` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:45:12
+   |
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |            ^^^^^^^     - variable not in all patterns
+   |            |
+   |            pattern doesn't bind `c`
+
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:45:22
    |
@@ -96,12 +104,12 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                 variable not in all patterns
 
 error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:12
+  --> $DIR/missing-bindings.rs:45:33
    |
 LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
-   |            ^^^^^^^     - variable not in all patterns
-   |            |
-   |            pattern doesn't bind `c`
+   |                        -        ^^^^ pattern doesn't bind `c`
+   |                        |
+   |                        variable not in all patterns
 
 error[E0408]: variable `d` is not bound in all patterns
   --> $DIR/missing-bindings.rs:45:33
@@ -135,14 +143,6 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                 |
    |                 variable not in all patterns
 
-error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:33
-   |
-LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
-   |                        -        ^^^^ pattern doesn't bind `c`
-   |                        |
-   |                        variable not in all patterns
-
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:61:29
    |
@@ -185,6 +185,28 @@ LL |                     B(b),
 LL |                 B(_)
    |                 ^^^^ pattern doesn't bind `b`
 
+error[E0408]: variable `c` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:57:13
+   |
+LL | /             V1(
+LL | |
+LL | |
+LL | |                 A(
+...  |
+LL | |                 B(Ok(a) | Err(a))
+LL | |             ) |
+   | |_____________^ pattern doesn't bind `c`
+LL | /             V2(
+LL | |                 A(
+LL | |                     A(_, a) |
+LL | |                     B(b),
+...  |
+LL | |
+LL | |             ) |
+   | |_____________^ pattern doesn't bind `c`
+LL |               V3(c),
+   |                  - variable not in all patterns
+
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:76:13
    |
@@ -215,28 +237,6 @@ LL |                       B(b),
 LL |               V3(c),
    |               ^^^^^ pattern doesn't bind `b`
 
-error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:57:13
-   |
-LL | /             V1(
-LL | |
-LL | |
-LL | |                 A(
-...  |
-LL | |                 B(Ok(a) | Err(a))
-LL | |             ) |
-   | |_____________^ pattern doesn't bind `c`
-LL | /             V2(
-LL | |                 A(
-LL | |                     A(_, a) |
-LL | |                     B(b),
-...  |
-LL | |
-LL | |             ) |
-   | |_____________^ pattern doesn't bind `c`
-LL |               V3(c),
-   |                  - variable not in all patterns
-
 error: aborting due to 26 previous errors
 
 For more information about this error, try `rustc --explain E0408`.
diff --git a/tests/ui/resolve/resolve-inconsistent-names.stderr b/tests/ui/resolve/resolve-inconsistent-names.stderr
index 023db303dd0..42b7281d7b0 100644
--- a/tests/ui/resolve/resolve-inconsistent-names.stderr
+++ b/tests/ui/resolve/resolve-inconsistent-names.stderr
@@ -14,6 +14,15 @@ LL |        a | b => {}
    |        |
    |        pattern doesn't bind `b`
 
+error[E0408]: variable `c` is not bound in all patterns
+  --> $DIR/resolve-inconsistent-names.rs:19:9
+   |
+LL |         (A, B) | (ref B, c) | (c, A) => ()
+   |         ^^^^^^           -     - variable not in all patterns
+   |         |                |
+   |         |                variable not in all patterns
+   |         pattern doesn't bind `c`
+
 error[E0408]: variable `A` is not bound in all patterns
   --> $DIR/resolve-inconsistent-names.rs:19:18
    |
@@ -37,15 +46,6 @@ LL |         (A, B) | (ref B, c) | (c, A) => ()
    |             |         variable not in all patterns
    |             variable not in all patterns
 
-error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/resolve-inconsistent-names.rs:19:9
-   |
-LL |         (A, B) | (ref B, c) | (c, A) => ()
-   |         ^^^^^^           -     - variable not in all patterns
-   |         |                |
-   |         |                variable not in all patterns
-   |         pattern doesn't bind `c`
-
 error[E0409]: variable `B` is bound inconsistently across alternatives separated by `|`
   --> $DIR/resolve-inconsistent-names.rs:19:23
    |
diff --git a/tests/ui/span/issue-39698.stderr b/tests/ui/span/issue-39698.stderr
index 25c35fd5479..81211b20a01 100644
--- a/tests/ui/span/issue-39698.stderr
+++ b/tests/ui/span/issue-39698.stderr
@@ -1,3 +1,13 @@
+error[E0408]: variable `c` is not bound in all patterns
+  --> $DIR/issue-39698.rs:10:9
+   |
+LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+   |         ^^^^^^^^^^^   ^^^^^^^^^^^         -    ^^^^^^^^ pattern doesn't bind `c`
+   |         |             |                   |
+   |         |             |                   variable not in all patterns
+   |         |             pattern doesn't bind `c`
+   |         pattern doesn't bind `c`
+
 error[E0408]: variable `d` is not bound in all patterns
   --> $DIR/issue-39698.rs:10:37
    |
@@ -28,16 +38,6 @@ LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
    |         |                      variable not in all patterns
    |         pattern doesn't bind `b`
 
-error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/issue-39698.rs:10:9
-   |
-LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
-   |         ^^^^^^^^^^^   ^^^^^^^^^^^         -    ^^^^^^^^ pattern doesn't bind `c`
-   |         |             |                   |
-   |         |             |                   variable not in all patterns
-   |         |             pattern doesn't bind `c`
-   |         pattern doesn't bind `c`
-
 error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0408`.