aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend/rust-constexpr.cc
diff options
context:
space:
mode:
authorFaisal Abbas <90.abbasfaisal@gmail.com>2022-07-29 05:35:34 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-08-25 12:40:25 +0100
commite991065fdbee901d4bfe3af89e0d497e74dcc7d3 (patch)
tree52b131e172be05cdfd75ec3f60ba805a117201d4 /gcc/rust/backend/rust-constexpr.cc
parentf21f475feca30d0c9fb74dfe3bb65a6d88d5311c (diff)
downloadgcc-e991065fdbee901d4bfe3af89e0d497e74dcc7d3.zip
gcc-e991065fdbee901d4bfe3af89e0d497e74dcc7d3.tar.gz
gcc-e991065fdbee901d4bfe3af89e0d497e74dcc7d3.tar.bz2
rust-constexpr.cc: port over cxx_eval_switch_expr
Diffstat (limited to 'gcc/rust/backend/rust-constexpr.cc')
-rw-r--r--gcc/rust/backend/rust-constexpr.cc56
1 files changed, 56 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index cac28d6..127451e 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -497,6 +497,10 @@ static tree
eval_loop_expr (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
bool *overflow_p, tree *jump_target);
+static tree
+eval_switch_expr (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
+ bool *overflow_p, tree *jump_target);
+
/* Variables and functions to manage constexpr call expansion context.
These do not need to be marked for PCH or GC. */
@@ -741,6 +745,11 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
eval_loop_expr (ctx, t, non_constant_p, overflow_p, jump_target);
break;
+ case SWITCH_EXPR:
+ case SWITCH_STMT:
+ eval_switch_expr (ctx, t, non_constant_p, overflow_p, jump_target);
+ break;
+
case BIT_FIELD_REF:
r = eval_bit_field_ref (ctx, t, lval, non_constant_p, overflow_p);
break;
@@ -2771,6 +2780,8 @@ eval_bit_field_ref (const constexpr_ctx *ctx, tree t, bool lval,
return error_mark_node;
}
+// forked from gcc/cp/constexpr.cc returns
+
/* Predicates for the meaning of *jump_target. */
static bool
@@ -2782,6 +2793,8 @@ returns (tree *jump_target)
&& LABEL_DECL_CDTOR (*jump_target)));
}
+// forked from gcc/cp/constexpr.cc breaks
+
static bool
breaks (tree *jump_target)
{
@@ -2792,6 +2805,8 @@ breaks (tree *jump_target)
|| TREE_CODE (*jump_target) == EXIT_EXPR);
}
+// forked from gcc/cp/constexpr.cc continues
+
static bool
continues (tree *jump_target)
{
@@ -2801,12 +2816,16 @@ continues (tree *jump_target)
|| TREE_CODE (*jump_target) == CONTINUE_STMT);
}
+// forked from gcc/cp/constexpr.cc switches
+
static bool
switches (tree *jump_target)
{
return *jump_target && TREE_CODE (*jump_target) == INTEGER_CST;
}
+// forked from gcc/cp/constexpr.cc cxx_eval_loop_expr
+
/* Evaluate a LOOP_EXPR for side-effects. Handles break and return
semantics; continue semantics are covered by cxx_eval_statement_list. */
@@ -2914,6 +2933,43 @@ eval_loop_expr (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
return NULL_TREE;
}
+// forked from gcc/cp/constexpr.cc cxx_eval_switch_expr
+
+/* Evaluate a SWITCH_EXPR for side-effects. Handles switch and break jump
+ semantics. */
+
+static tree
+eval_switch_expr (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
+ bool *overflow_p, tree *jump_target)
+{
+ tree cond
+ = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_COND (t) : SWITCH_COND (t);
+ cond
+ = eval_constant_expression (ctx, cond, false, non_constant_p, overflow_p);
+ VERIFY_CONSTANT (cond);
+ *jump_target = cond;
+
+ tree body
+ = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_BODY (t) : SWITCH_BODY (t);
+ constexpr_ctx new_ctx = *ctx;
+ constexpr_switch_state css = css_default_not_seen;
+ new_ctx.css_state = &css;
+ eval_constant_expression (&new_ctx, body, false, non_constant_p, overflow_p,
+ jump_target);
+ if (switches (jump_target) && css == css_default_seen)
+ {
+ /* If the SWITCH_EXPR body has default: label, process it once again,
+ this time instructing label_matches to return true for default:
+ label on switches (jump_target). */
+ css = css_default_processing;
+ eval_constant_expression (&new_ctx, body, false, non_constant_p,
+ overflow_p, jump_target);
+ }
+ if (breaks (jump_target) || switches (jump_target))
+ *jump_target = NULL_TREE;
+ return NULL_TREE;
+}
+
// #include "gt-rust-rust-constexpr.h"
} // namespace Compile