diff options
Diffstat (limited to 'gcc/cp/semantics.c')
| -rw-r--r-- | gcc/cp/semantics.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 2d64a66..d45a6e2 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -6209,7 +6209,7 @@ explain_invalid_constexpr_fn (tree fun) typedef struct GTY(()) constexpr_call { /* Description of the constexpr function definition. */ constexpr_fundef *fundef; - /* Parameter bindings enironment. A TREE_LIST where each TREE_PURPOSE + /* Parameter bindings environment. A TREE_LIST where each TREE_PURPOSE is a parameter _DECL and the TREE_VALUE is the value of the parameter. Note: This arrangement is made to accomodate the use of iterative_hash_template_arg (see pt.c). If you change this @@ -6233,6 +6233,9 @@ static GTY ((param_is (constexpr_call))) htab_t constexpr_call_table; static tree cxx_eval_constant_expression (const constexpr_call *, tree, bool, bool, bool *); +static tree cxx_eval_vec_perm_expr (const constexpr_call *, tree, bool, bool, + bool *); + /* Compute a hash value for a constexpr call representation. */ @@ -7495,6 +7498,39 @@ non_const_var_error (tree r) } } +/* Evaluate VEC_PERM_EXPR (v1, v2, mask). */ +static tree +cxx_eval_vec_perm_expr (const constexpr_call *call, tree t, + bool allow_non_constant, bool addr, + bool * non_constant_p) +{ + int i; + tree args[3]; + tree val; + tree elttype = TREE_TYPE (t); + + for (i = 0; i < 3; i++) + { + args[i] = cxx_eval_constant_expression (call, TREE_OPERAND (t, i), + allow_non_constant, addr, + non_constant_p); + if (*non_constant_p) + goto fail; + } + + gcc_assert (TREE_CODE (TREE_TYPE (args[0])) == VECTOR_TYPE); + gcc_assert (TREE_CODE (TREE_TYPE (args[1])) == VECTOR_TYPE); + gcc_assert (TREE_CODE (TREE_TYPE (args[2])) == VECTOR_TYPE); + + val = fold_ternary_loc (EXPR_LOCATION (t), VEC_PERM_EXPR, elttype, + args[0], args[1], args[2]); + if (val != NULL_TREE) + return val; + + fail: + return t; +} + /* Attempt to reduce the expression T to a constant value. On failure, issue diagnostic and return error_mark_node. */ /* FIXME unify with c_fully_fold */ @@ -7773,6 +7809,11 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t, non_constant_p); break; + case VEC_PERM_EXPR: + r = cxx_eval_vec_perm_expr (call, t, allow_non_constant, addr, + non_constant_p); + break; + case CONVERT_EXPR: case VIEW_CONVERT_EXPR: case NOP_EXPR: |
