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, "% 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, "% 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; +}