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