[COMMITTED 42/43] gccrs: Port over missing GOTO handling from cp/constexpr.cc

arthur.cohen@opensrcsec.com arthur.cohen@opensrcsec.com
Thu Sep 10 08:19:55 GMT 2026


From: Philip Herron <herron.philip@googlemail.com>

Fixes Rust-GCC/gccrs#1553

gcc/rust/ChangeLog:

	* backend/rust-constexpr.cc (eval_constant_expression): port over goto
	(potential_constant_expression_1): likewise

gcc/testsuite/ChangeLog:

	* rust/compile/issue-1553.rs: New test.

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
---
 gcc/rust/backend/rust-constexpr.cc       | 44 ++++++++++++++++++++++--
 gcc/testsuite/rust/compile/issue-1553.rs | 20 +++++++++++
 2 files changed, 61 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-1553.rs

diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index 908064394e7..22d0ed3bd29 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -1918,6 +1918,9 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
 			  bool *non_constant_p, bool *overflow_p,
 			  tree *jump_target)
 {
+  if (t == NULL_TREE)
+    return NULL_TREE;
+
   if (jump_target && *jump_target)
     {
       /* If we are jumping, ignore all statements/expressions except those
@@ -1951,9 +1954,6 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
 
   location_t loc = EXPR_LOCATION (t);
 
-  if (t == NULL_TREE)
-    return NULL_TREE;
-
   if (CONSTANT_CLASS_P (t))
     {
       if (TREE_OVERFLOW (t))
@@ -2390,6 +2390,29 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
 				 jump_target);
       break;
 
+    case GOTO_EXPR:
+      {
+	tree target = TREE_OPERAND (t, 0);
+	if (breaks (&target) || continues (&target) || returns (&target)
+	    || (TREE_CODE (target) == LABEL_DECL && DECL_ARTIFICIAL (target)))
+	  {
+	    if (jump_target)
+	      *jump_target = target;
+	    else
+	      {
+		gcc_assert (ctx->quiet);
+		*non_constant_p = true;
+	      }
+	  }
+	else
+	  {
+	    if (!ctx->quiet)
+	      error_at (loc, "%<goto%> is not a constant expression");
+	    *non_constant_p = true;
+	  }
+      }
+      break;
+
     case LOOP_EXPR:
     case WHILE_STMT:
     case FOR_STMT:
@@ -6655,6 +6678,21 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
       /* We can see these in statement-expressions.  */
       return true;
 
+    case GOTO_EXPR:
+      {
+	tree *target = &TREE_OPERAND (t, 0);
+	if (breaks (target) || continues (target) || returns (target))
+	  {
+	    *jump_target = *target;
+	    return true;
+	  }
+	if (TREE_CODE (*target) == LABEL_DECL && DECL_ARTIFICIAL (*target))
+	  return true;
+	if (flags & tf_error)
+	  error_at (loc, "%<goto%> is not a constant expression");
+	return false;
+      }
+
     case LABEL_EXPR:
       t = LABEL_EXPR_LABEL (t);
       if (DECL_ARTIFICIAL (t))
diff --git a/gcc/testsuite/rust/compile/issue-1553.rs b/gcc/testsuite/rust/compile/issue-1553.rs
new file mode 100644
index 00000000000..c562ac88a14
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1553.rs
@@ -0,0 +1,20 @@
+// { dg-options "-w -O0 -fdump-tree-gimple" }
+#![feature(no_core)]
+#![no_core]
+
+const fn test(x: i32) -> i32 {
+    return match x {
+        0 => 100,
+        _ => 200,
+    };
+}
+
+const X: i32 = test(0);
+const Y: i32 = test(1);
+
+fn main() {
+    // { dg-final { scan-tree-dump-times {x = 100} 1 gimple } }
+    let x = X;
+    // { dg-final { scan-tree-dump-times {y = 200} 1 gimple } }
+    let y = Y;
+}
-- 
2.50.1



More information about the Gcc-rust mailing list