From: Yap Zhi Heng <[email protected]>
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 <[email protected]>
---
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 c29359aebe9..708a824ad4d 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -121,8 +121,8 @@ compile_range_pattern_bound (HIR::RangePatternBound &bound,
HIR::LiteralExpr litexpr (mappings, ref.get_literal (), locus,
std::vector<AST::Attribute> ());
- if (ref.get_has_minus())
- litexpr.set_negative();
+ if (ref.get_has_minus ())
+ litexpr.set_negative ();
result = CompileExpr::Compile (litexpr, ctx);
}
@@ -163,6 +163,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,
+ };
+}
--
2.50.1