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

Reply via email to