From dd626f58150a9d7e32ce72510ebe77c0bfa09fe4 Mon Sep 17 00:00:00 2001 From: wisp3rwind <17089248+wisp3rwind@users.noreply.github.com> Date: Sun, 28 Sep 2025 17:54:19 +0200 Subject: [PATCH] fix: don't crash when target-feature=+relax is given This target feature is a bit unusual in that it does not refer to actual hardware features, but is rather a target-specific linker feature. See also https://github.com/rust-lang/rust/pull/109860 --- riscv-target-parser/CHANGELOG.md | 4 ++++ riscv-target-parser/src/lib.rs | 20 +++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/riscv-target-parser/CHANGELOG.md b/riscv-target-parser/CHANGELOG.md index b805fb6e..939f90ac 100644 --- a/riscv-target-parser/CHANGELOG.md +++ b/riscv-target-parser/CHANGELOG.md @@ -5,6 +5,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed + +- Skip the 'relax' target feature when parsing extensions + ## [v0.1.2] - 2025-06-10 ### Fixed diff --git a/riscv-target-parser/src/lib.rs b/riscv-target-parser/src/lib.rs index b557d619..2d39c17a 100644 --- a/riscv-target-parser/src/lib.rs +++ b/riscv-target-parser/src/lib.rs @@ -106,6 +106,12 @@ pub struct RiscvTarget { extensions: Extensions, } +// Returns whether a target feature _might_ be an ISA extension according to a non-exhaustive list +// of known unrelated features flags. +fn is_isa_extension(feature: &str) -> bool { + feature != "relax" +} + impl RiscvTarget { /// Builds a RISC-V target from a target triple and cargo flags. /// This function is expected to be called from a build script. @@ -135,11 +141,15 @@ impl RiscvTarget { }) { if let Some(feature) = target_feature.strip_prefix('+') { - let extension = Extension::try_from(feature)?; - target.extensions.insert(extension); + if is_isa_extension(feature) { + let extension = Extension::try_from(feature)?; + target.extensions.insert(extension); + } } else if let Some(feature) = target_feature.strip_prefix('-') { - let extension = Extension::try_from(feature)?; - target.extensions.remove(&extension); + if is_isa_extension(feature) { + let extension = Extension::try_from(feature)?; + target.extensions.remove(&extension); + } } else { return Err(Error::UnknownTargetFeature(target_feature)); } @@ -246,7 +256,7 @@ mod test { #[test] fn test_parse_target() { let target = "riscv32imac-unknown-none-elf"; - let cargo_flags = "target-feature=+m,-a,+f"; + let cargo_flags = "target-feature=+m,-a,+f,+relax"; let target = super::RiscvTarget::build(target, cargo_flags).unwrap(); let rustc_flags = target.rustc_flags(); assert_eq!(rustc_flags, vec!["riscvi", "riscvm", "riscvf", "riscvc"]);