]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Implement E0579 error checking in RangePattern compilation
authorYap Zhi Heng <yapzhhg@gmail.com>
Mon, 20 Oct 2025 06:01:40 +0000 (14:01 +0800)
committerArthur Cohen <arthur.cohen@embecosm.com>
Mon, 17 Nov 2025 14:58:18 +0000 (15:58 +0100)
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 <yapzhhg@gmail.com>
gcc/rust/backend/rust-compile-pattern.cc
gcc/testsuite/rust/compile/issue-3659.rs [new file with mode: 0644]

index c29359aebe96458656ee741364c2c844ad770b88..708a824ad4d582630b9e906bdea17a82a2abe11c 100644 (file)
@@ -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 (file)
index 0000000..ffbc634
--- /dev/null
@@ -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,
+    };
+}