From: Philip Herron <[email protected]>

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 <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/a263235e4f9da943366e08ebc4ecb799c50738bd

The commit has been mentioned in the following issue(s):
 - Rust-GCC/gccrs#1553: https://github.com/Rust-GCC/gccrs/issues/1553

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4796

 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 908064394..22d0ed3bd 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 000000000..c562ac88a
--- /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;
+}

base-commit: 0029e0e44559501663f95997a892a2a701d95840
-- 
2.54.0

Reply via email to