From dcd4d2f78a44dca83bb36b472b2299e7132853f5 Mon Sep 17 00:00:00 2001 From: Yap Zhi Heng Date: Sun, 26 Oct 2025 11:13:25 +0800 Subject: [PATCH 1/2] gccrs: Fix `RangePattern` negative literal bounds being treated as positive GIMPLE output for compile/issue-4242.rs: ... x = 1; RUSTTMP.2 = x; _1 = RUSTTMP.2 >= -55; _2 = RUSTTMP.2 < 0; _3 = _1 & _2; if (_3 != 0) goto ; else goto ; : { RUSTTMP.1 = 2; goto ; } : _4 = RUSTTMP.2 >= -99; _5 = RUSTTMP.2 < -55; _6 = _4 & _5; if (_6 != 0) goto ; else goto ; : { RUSTTMP.1 = 3; goto ; } ... gcc/rust/ChangeLog: * backend/rust-compile-pattern.cc (compile_range_pattern_bound): Set litexpr to negative if has_minus is present in the RangePatternBoundLiteral param. Signed-off-by: Yap Zhi Heng --- gcc/rust/backend/rust-compile-pattern.cc | 2 ++ gcc/testsuite/rust/compile/issue-4242.rs | 10 ++++++++++ gcc/testsuite/rust/execute/torture/issue-4242.rs | 11 +++++++++++ 3 files changed, 23 insertions(+) create mode 100644 gcc/testsuite/rust/compile/issue-4242.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-4242.rs diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc index 82333dc39c0..32ce6a61bb2 100644 --- a/gcc/rust/backend/rust-compile-pattern.cc +++ b/gcc/rust/backend/rust-compile-pattern.cc @@ -119,6 +119,8 @@ compile_range_pattern_bound (HIR::RangePatternBound &bound, HIR::LiteralExpr litexpr (mappings, ref.get_literal (), locus, std::vector ()); + if (ref.get_has_minus()) + litexpr.set_negative(); result = CompileExpr::Compile (litexpr, ctx); } diff --git a/gcc/testsuite/rust/compile/issue-4242.rs b/gcc/testsuite/rust/compile/issue-4242.rs new file mode 100644 index 00000000000..ecbe258cec6 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-4242.rs @@ -0,0 +1,10 @@ +#![feature(exclusive_range_pattern)] + +fn main() { + let x = 1; + + match x { + -55..0 => 2, + -99..-55 => 3, + }; +} \ No newline at end of file diff --git a/gcc/testsuite/rust/execute/torture/issue-4242.rs b/gcc/testsuite/rust/execute/torture/issue-4242.rs new file mode 100644 index 00000000000..867adc98e30 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-4242.rs @@ -0,0 +1,11 @@ +#![feature(exclusive_range_pattern)] + +fn main() -> i32 { + let x = -77; + + match x { + -55..99 => 1, + -99..-55 => 0, // the correct case + _ => 1, + } +} \ No newline at end of file From 8ee2b1533b46e7688cd1b02505148848590389ee Mon Sep 17 00:00:00 2001 From: Yap Zhi Heng Date: Mon, 20 Oct 2025 14:01:40 +0800 Subject: [PATCH 2/2] gccrs: Implement E0579 error checking in RangePattern compilation Checks whether upper bound of range is not lower or equal to the lower bound. gcc/rust/ChangeLog: * backend/rust-compile-pattern.cc(compilePatternCheckExpr::visit(RangePattern)): Add E0579 check to ensure that lower bound is always below upper bound. Signed-off-by: Yap Zhi Heng --- gcc/rust/backend/rust-compile-pattern.cc | 28 ++++++++++++++++++++++-- gcc/testsuite/rust/compile/issue-3659.rs | 10 +++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/rust/compile/issue-3659.rs diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc index 32ce6a61bb2..20756ec3b2e 100644 --- a/gcc/rust/backend/rust-compile-pattern.cc +++ b/gcc/rust/backend/rust-compile-pattern.cc @@ -119,8 +119,8 @@ compile_range_pattern_bound (HIR::RangePatternBound &bound, HIR::LiteralExpr litexpr (mappings, ref.get_literal (), locus, std::vector ()); - if (ref.get_has_minus()) - litexpr.set_negative(); + if (ref.get_has_minus ()) + litexpr.set_negative (); result = CompileExpr::Compile (litexpr, ctx); } @@ -161,6 +161,30 @@ CompilePatternCheckExpr::visit (HIR::RangePattern &pattern) pattern.get_mappings (), pattern.get_locus (), ctx); + rust_assert ( + (TREE_CODE (upper) == REAL_CST && TREE_CODE (lower) == REAL_CST) + || (TREE_CODE (upper) == INTEGER_CST && TREE_CODE (lower) == INTEGER_CST)); + + bool error_E0579 = false; + if (TREE_CODE (upper) == REAL_CST) + { + REAL_VALUE_TYPE upper_r = TREE_REAL_CST (upper); + REAL_VALUE_TYPE lower_r = TREE_REAL_CST (lower); + if (real_compare (GE_EXPR, &lower_r, &upper_r)) + error_E0579 = true; + } + else if (TREE_CODE (upper) == INTEGER_CST) + { + auto upper_wi = wi::to_wide (upper).to_shwi (); + auto lower_wi = wi::to_wide (lower).to_shwi (); + if (lower_wi >= upper_wi) + error_E0579 = true; + } + + if (error_E0579) + rust_error_at (pattern.get_locus (), ErrorCode::E0579, + "lower range bound must be less than upper"); + ComparisonOperator upper_cmp = pattern.is_inclusive_range () ? ComparisonOperator::LESS_OR_EQUAL : ComparisonOperator::LESS_THAN; diff --git a/gcc/testsuite/rust/compile/issue-3659.rs b/gcc/testsuite/rust/compile/issue-3659.rs new file mode 100644 index 00000000000..ffbc63481b6 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3659.rs @@ -0,0 +1,10 @@ +#![feature(exclusive_range_pattern)] + +fn main() { + let x = 3; + + match x { + 0..-1 => 2, // { dg-error "lower range bound must be less than upper .E0579." } + _ => 3, + }; +}