diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc index 82333dc39c0..20756ec3b2e 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); } @@ -159,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, + }; +} 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