constexpr.c (struct constexpr_ctx): Add quiet field.

* constexpr.c (struct constexpr_ctx): Add quiet field.
	(cxx_eval_outermost_constant_expr, is_sub_constant_expr): Set it.
	(lots): Replace allow_non_constant parameter with ctx->quiet.

From-SVN: r217746
This commit is contained in:
Jason Merrill 2014-11-18 22:03:28 -05:00 committed by Jason Merrill
parent 643266a5a5
commit 2b3ab879c7
2 changed files with 124 additions and 124 deletions

View File

@ -1,5 +1,9 @@
2014-11-18 Jason Merrill <jason@redhat.com> 2014-11-18 Jason Merrill <jason@redhat.com>
* constexpr.c (struct constexpr_ctx): Add quiet field.
(cxx_eval_outermost_constant_expr, is_sub_constant_expr): Set it.
(lots): Replace allow_non_constant parameter with ctx->quiet.
PR c++/63940 PR c++/63940
* constexpr.c (cxx_eval_binary_expression): Don't assume the * constexpr.c (cxx_eval_binary_expression): Don't assume the
expression was already folded. expression was already folded.

View File

@ -36,7 +36,7 @@ along with GCC; see the file COPYING3. If not see
static bool verify_constant (tree, bool, bool *, bool *); static bool verify_constant (tree, bool, bool *, bool *);
#define VERIFY_CONSTANT(X) \ #define VERIFY_CONSTANT(X) \
do { \ do { \
if (verify_constant ((X), allow_non_constant, non_constant_p, overflow_p)) \ if (verify_constant ((X), ctx->quiet, non_constant_p, overflow_p)) \
return t; \ return t; \
} while (0) } while (0)
@ -863,6 +863,7 @@ struct constexpr_ctx {
hash_map<tree,tree> *values; hash_map<tree,tree> *values;
tree ctor; tree ctor;
tree object; tree object;
bool quiet;
}; };
/* A table of all constexpr calls that have been evaluated by the /* A table of all constexpr calls that have been evaluated by the
@ -871,7 +872,7 @@ struct constexpr_ctx {
static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table; static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
static tree cxx_eval_constant_expression (const constexpr_ctx *, tree, static tree cxx_eval_constant_expression (const constexpr_ctx *, tree,
bool, bool, bool *, bool *, tree *); bool, bool *, bool *, tree *);
/* Compute a hash value for a constexpr call representation. */ /* Compute a hash value for a constexpr call representation. */
@ -982,7 +983,7 @@ lookup_parameter_binding (const constexpr_call *call, tree t)
static tree static tree
cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
const int nargs = call_expr_nargs (t); const int nargs = call_expr_nargs (t);
@ -992,10 +993,10 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t,
for (i = 0; i < nargs; ++i) for (i = 0; i < nargs; ++i)
{ {
args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, i), args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, i),
allow_non_constant, addr, addr,
non_constant_p, overflow_p, non_constant_p, overflow_p,
NULL); NULL);
if (allow_non_constant && *non_constant_p) if (ctx->quiet && *non_constant_p)
return t; return t;
} }
if (*non_constant_p) if (*non_constant_p)
@ -1034,7 +1035,6 @@ adjust_temp_type (tree type, tree temp)
static void static void
cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
constexpr_call *new_call, constexpr_call *new_call,
bool allow_non_constant,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
const int nargs = call_expr_nargs (t); const int nargs = call_expr_nargs (t);
@ -1067,11 +1067,11 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
type = TREE_TYPE (type); type = TREE_TYPE (type);
x = convert_from_reference (x); x = convert_from_reference (x);
} }
arg = cxx_eval_constant_expression (ctx, x, allow_non_constant, arg = cxx_eval_constant_expression (ctx, x,
TREE_CODE (type) == REFERENCE_TYPE, TREE_CODE (type) == REFERENCE_TYPE,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
/* Don't VERIFY_CONSTANT here. */ /* Don't VERIFY_CONSTANT here. */
if (*non_constant_p && allow_non_constant) if (*non_constant_p && ctx->quiet)
return; return;
/* Just discard ellipsis args after checking their constantitude. */ /* Just discard ellipsis args after checking their constantitude. */
if (!parms) if (!parms)
@ -1134,7 +1134,7 @@ cx_error_context (void)
static tree static tree
cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
location_t loc = EXPR_LOC_OR_LOC (t, input_location); location_t loc = EXPR_LOC_OR_LOC (t, input_location);
@ -1148,7 +1148,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
if (TREE_CODE (fun) != FUNCTION_DECL) if (TREE_CODE (fun) != FUNCTION_DECL)
{ {
/* Might be a constexpr function pointer. */ /* Might be a constexpr function pointer. */
fun = cxx_eval_constant_expression (ctx, fun, allow_non_constant, fun = cxx_eval_constant_expression (ctx, fun,
/*addr*/false, non_constant_p, /*addr*/false, non_constant_p,
overflow_p, NULL); overflow_p, NULL);
STRIP_NOPS (fun); STRIP_NOPS (fun);
@ -1157,7 +1157,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
} }
if (TREE_CODE (fun) != FUNCTION_DECL) if (TREE_CODE (fun) != FUNCTION_DECL)
{ {
if (!allow_non_constant && !*non_constant_p) if (!ctx->quiet && !*non_constant_p)
error_at (loc, "expression %qE does not designate a constexpr " error_at (loc, "expression %qE does not designate a constexpr "
"function", fun); "function", fun);
*non_constant_p = true; *non_constant_p = true;
@ -1166,11 +1166,11 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
if (DECL_CLONED_FUNCTION_P (fun)) if (DECL_CLONED_FUNCTION_P (fun))
fun = DECL_CLONED_FUNCTION (fun); fun = DECL_CLONED_FUNCTION (fun);
if (is_builtin_fn (fun)) if (is_builtin_fn (fun))
return cxx_eval_builtin_function_call (ctx, t, allow_non_constant, return cxx_eval_builtin_function_call (ctx, t,
addr, non_constant_p, overflow_p); addr, non_constant_p, overflow_p);
if (!DECL_DECLARED_CONSTEXPR_P (fun)) if (!DECL_DECLARED_CONSTEXPR_P (fun))
{ {
if (!allow_non_constant) if (!ctx->quiet)
{ {
error_at (loc, "call to non-constexpr function %qD", fun); error_at (loc, "call to non-constexpr function %qD", fun);
explain_invalid_constexpr_fn (fun); explain_invalid_constexpr_fn (fun);
@ -1185,7 +1185,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
if (call_expr_nargs (t) == 2) if (call_expr_nargs (t) == 2)
{ {
tree arg = convert_from_reference (get_nth_callarg (t, 1)); tree arg = convert_from_reference (get_nth_callarg (t, 1));
return cxx_eval_constant_expression (ctx, arg, allow_non_constant, return cxx_eval_constant_expression (ctx, arg,
addr, non_constant_p, addr, non_constant_p,
overflow_p, NULL); overflow_p, NULL);
} }
@ -1202,7 +1202,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
new_call.fundef = retrieve_constexpr_fundef (fun); new_call.fundef = retrieve_constexpr_fundef (fun);
if (new_call.fundef == NULL || new_call.fundef->body == NULL) if (new_call.fundef == NULL || new_call.fundef->body == NULL)
{ {
if (!allow_non_constant) if (!ctx->quiet)
{ {
if (DECL_INITIAL (fun)) if (DECL_INITIAL (fun))
{ {
@ -1232,7 +1232,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
} }
cxx_bind_parameters_in_call (ctx, t, &new_call, cxx_bind_parameters_in_call (ctx, t, &new_call,
allow_non_constant, non_constant_p, overflow_p); non_constant_p, overflow_p);
if (*non_constant_p) if (*non_constant_p)
return t; return t;
@ -1257,7 +1257,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
so that we can detect circular dependencies. */ so that we can detect circular dependencies. */
else if (entry->result == NULL) else if (entry->result == NULL)
{ {
if (!allow_non_constant) if (!ctx->quiet)
error ("call has circular dependency"); error ("call has circular dependency");
*non_constant_p = true; *non_constant_p = true;
entry->result = result = error_mark_node; entry->result = result = error_mark_node;
@ -1265,7 +1265,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
if (!depth_ok) if (!depth_ok)
{ {
if (!allow_non_constant) if (!ctx->quiet)
error ("constexpr evaluation depth exceeds maximum of %d (use " error ("constexpr evaluation depth exceeds maximum of %d (use "
"-fconstexpr-depth= to increase the maximum)", "-fconstexpr-depth= to increase the maximum)",
max_constexpr_depth); max_constexpr_depth);
@ -1282,7 +1282,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
new_ctx.call = &new_call; new_ctx.call = &new_call;
result = (cxx_eval_constant_expression result = (cxx_eval_constant_expression
(&new_ctx, new_call.fundef->body, (&new_ctx, new_call.fundef->body,
allow_non_constant, addr, addr,
non_constant_p, overflow_p, NULL)); non_constant_p, overflow_p, NULL));
} }
else else
@ -1324,7 +1324,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
ctx->values->put (res, NULL_TREE); ctx->values->put (res, NULL_TREE);
tree jump_target = NULL_TREE; tree jump_target = NULL_TREE;
cxx_eval_constant_expression (ctx, body, allow_non_constant, cxx_eval_constant_expression (ctx, body,
addr, non_constant_p, overflow_p, addr, non_constant_p, overflow_p,
&jump_target); &jump_target);
@ -1340,7 +1340,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
result = *ctx->values->get (slot ? slot : res); result = *ctx->values->get (slot ? slot : res);
if (result == NULL_TREE) if (result == NULL_TREE)
{ {
if (!allow_non_constant) if (!ctx->quiet)
error ("constexpr call flows off the end " error ("constexpr call flows off the end "
"of the function"); "of the function");
*non_constant_p = true; *non_constant_p = true;
@ -1452,12 +1452,12 @@ verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
static tree static tree
cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t, cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
tree r; tree r;
tree orig_arg = TREE_OPERAND (t, 0); tree orig_arg = TREE_OPERAND (t, 0);
tree arg = cxx_eval_constant_expression (ctx, orig_arg, allow_non_constant, tree arg = cxx_eval_constant_expression (ctx, orig_arg,
addr, non_constant_p, overflow_p, addr, non_constant_p, overflow_p,
NULL); NULL);
VERIFY_CONSTANT (arg); VERIFY_CONSTANT (arg);
@ -1481,7 +1481,7 @@ cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
static tree static tree
cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t, cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
tree r; tree r;
@ -1489,11 +1489,11 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
tree orig_rhs = TREE_OPERAND (t, 1); tree orig_rhs = TREE_OPERAND (t, 1);
tree lhs, rhs; tree lhs, rhs;
lhs = cxx_eval_constant_expression (ctx, orig_lhs, lhs = cxx_eval_constant_expression (ctx, orig_lhs,
allow_non_constant, addr, addr,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
VERIFY_CONSTANT (lhs); VERIFY_CONSTANT (lhs);
rhs = cxx_eval_constant_expression (ctx, orig_rhs, rhs = cxx_eval_constant_expression (ctx, orig_rhs,
allow_non_constant, addr, addr,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
VERIFY_CONSTANT (rhs); VERIFY_CONSTANT (rhs);
@ -1518,23 +1518,23 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
static tree static tree
cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t, cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p, bool *non_constant_p, bool *overflow_p,
tree *jump_target) tree *jump_target)
{ {
tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
allow_non_constant, addr, addr,
non_constant_p, overflow_p, non_constant_p, overflow_p,
NULL); NULL);
VERIFY_CONSTANT (val); VERIFY_CONSTANT (val);
/* Don't VERIFY_CONSTANT the other operands. */ /* Don't VERIFY_CONSTANT the other operands. */
if (integer_zerop (val)) if (integer_zerop (val))
return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2), return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
allow_non_constant, addr, addr,
non_constant_p, overflow_p, non_constant_p, overflow_p,
jump_target); jump_target);
return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
allow_non_constant, addr, addr,
non_constant_p, overflow_p, non_constant_p, overflow_p,
jump_target); jump_target);
} }
@ -1544,12 +1544,12 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
static tree static tree
cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
tree oldary = TREE_OPERAND (t, 0); tree oldary = TREE_OPERAND (t, 0);
tree ary = cxx_eval_constant_expression (ctx, oldary, tree ary = cxx_eval_constant_expression (ctx, oldary,
allow_non_constant, addr, addr,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
tree index, oldidx; tree index, oldidx;
HOST_WIDE_INT i; HOST_WIDE_INT i;
@ -1559,7 +1559,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
return t; return t;
oldidx = TREE_OPERAND (t, 1); oldidx = TREE_OPERAND (t, 1);
index = cxx_eval_constant_expression (ctx, oldidx, index = cxx_eval_constant_expression (ctx, oldidx,
allow_non_constant, false, false,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
VERIFY_CONSTANT (index); VERIFY_CONSTANT (index);
if (addr && ary == oldary && index == oldidx) if (addr && ary == oldary && index == oldidx)
@ -1590,19 +1590,19 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
initializer, it's value-initialized. */ initializer, it's value-initialized. */
tree val = build_value_init (elem_type, tf_warning_or_error); tree val = build_value_init (elem_type, tf_warning_or_error);
return cxx_eval_constant_expression (ctx, val, return cxx_eval_constant_expression (ctx, val,
allow_non_constant, addr, addr,
non_constant_p, overflow_p, non_constant_p, overflow_p,
NULL); NULL);
} }
if (!allow_non_constant) if (!ctx->quiet)
error ("array subscript out of bound"); error ("array subscript out of bound");
*non_constant_p = true; *non_constant_p = true;
return t; return t;
} }
else if (tree_int_cst_lt (index, integer_zero_node)) else if (tree_int_cst_lt (index, integer_zero_node))
{ {
if (!allow_non_constant) if (!ctx->quiet)
error ("negative array subscript"); error ("negative array subscript");
*non_constant_p = true; *non_constant_p = true;
return t; return t;
@ -1628,7 +1628,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
static tree static tree
cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
unsigned HOST_WIDE_INT i; unsigned HOST_WIDE_INT i;
@ -1637,7 +1637,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
tree part = TREE_OPERAND (t, 1); tree part = TREE_OPERAND (t, 1);
tree orig_whole = TREE_OPERAND (t, 0); tree orig_whole = TREE_OPERAND (t, 0);
tree whole = cxx_eval_constant_expression (ctx, orig_whole, tree whole = cxx_eval_constant_expression (ctx, orig_whole,
allow_non_constant, addr, addr,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
if (whole == orig_whole) if (whole == orig_whole)
return t; return t;
@ -1648,13 +1648,13 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
CONSTRUCTOR. */ CONSTRUCTOR. */
if (!*non_constant_p && TREE_CODE (whole) != CONSTRUCTOR) if (!*non_constant_p && TREE_CODE (whole) != CONSTRUCTOR)
{ {
if (!allow_non_constant) if (!ctx->quiet)
error ("%qE is not a constant expression", orig_whole); error ("%qE is not a constant expression", orig_whole);
*non_constant_p = true; *non_constant_p = true;
} }
if (DECL_MUTABLE_P (part)) if (DECL_MUTABLE_P (part))
{ {
if (!allow_non_constant) if (!ctx->quiet)
error ("mutable %qD is not usable in a constant expression", part); error ("mutable %qD is not usable in a constant expression", part);
*non_constant_p = true; *non_constant_p = true;
} }
@ -1675,7 +1675,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
&& CONSTRUCTOR_NELTS (whole) > 0) && CONSTRUCTOR_NELTS (whole) > 0)
{ {
/* DR 1188 says we don't have to deal with this. */ /* DR 1188 says we don't have to deal with this. */
if (!allow_non_constant) if (!ctx->quiet)
error ("accessing %qD member instead of initialized %qD member in " error ("accessing %qD member instead of initialized %qD member in "
"constant expression", part, CONSTRUCTOR_ELT (whole, 0)->index); "constant expression", part, CONSTRUCTOR_ELT (whole, 0)->index);
*non_constant_p = true; *non_constant_p = true;
@ -1687,7 +1687,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
/* 'whole' is part of the aggregate initializer we're currently /* 'whole' is part of the aggregate initializer we're currently
building; if there's no initializer for this member yet, that's an building; if there's no initializer for this member yet, that's an
error. */ error. */
if (!allow_non_constant) if (!ctx->quiet)
error ("accessing uninitialized member %qD", part); error ("accessing uninitialized member %qD", part);
*non_constant_p = true; *non_constant_p = true;
return t; return t;
@ -1696,7 +1696,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
/* If there's no explicit init for this field, it's value-initialized. */ /* If there's no explicit init for this field, it's value-initialized. */
value = build_value_init (TREE_TYPE (t), tf_warning_or_error); value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
return cxx_eval_constant_expression (ctx, value, return cxx_eval_constant_expression (ctx, value,
allow_non_constant, addr, addr,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
} }
@ -1706,7 +1706,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
static tree static tree
cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t, cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
tree orig_whole = TREE_OPERAND (t, 0); tree orig_whole = TREE_OPERAND (t, 0);
@ -1714,7 +1714,7 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
bool fld_seen = false; bool fld_seen = false;
HOST_WIDE_INT istart, isize; HOST_WIDE_INT istart, isize;
tree whole = cxx_eval_constant_expression (ctx, orig_whole, tree whole = cxx_eval_constant_expression (ctx, orig_whole,
allow_non_constant, addr, addr,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
tree start, field, value; tree start, field, value;
unsigned HOST_WIDE_INT i; unsigned HOST_WIDE_INT i;
@ -1727,7 +1727,7 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
&& TREE_CODE (whole) != VECTOR_CST && TREE_CODE (whole) != VECTOR_CST
&& TREE_CODE (whole) != CONSTRUCTOR) && TREE_CODE (whole) != CONSTRUCTOR)
{ {
if (!allow_non_constant) if (!ctx->quiet)
error ("%qE is not a constant expression", orig_whole); error ("%qE is not a constant expression", orig_whole);
*non_constant_p = true; *non_constant_p = true;
} }
@ -1792,19 +1792,19 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
static tree static tree
cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t, cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t,
tree bailout_value, tree continue_value, tree bailout_value, tree continue_value,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
tree r; tree r;
tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
allow_non_constant, addr, addr,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
VERIFY_CONSTANT (lhs); VERIFY_CONSTANT (lhs);
if (tree_int_cst_equal (lhs, bailout_value)) if (tree_int_cst_equal (lhs, bailout_value))
return lhs; return lhs;
gcc_assert (tree_int_cst_equal (lhs, continue_value)); gcc_assert (tree_int_cst_equal (lhs, continue_value));
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
allow_non_constant, addr, non_constant_p, addr, non_constant_p,
overflow_p, NULL); overflow_p, NULL);
VERIFY_CONSTANT (r); VERIFY_CONSTANT (r);
return r; return r;
@ -1926,7 +1926,7 @@ verify_ctor_sanity (const constexpr_ctx *ctx, tree type)
static tree static tree
cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t); vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
@ -1947,11 +1947,11 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
initializers can refer to it. */ initializers can refer to it. */
CONSTRUCTOR_APPEND_ELT (*p, index, new_ctx.ctor); CONSTRUCTOR_APPEND_ELT (*p, index, new_ctx.ctor);
tree elt = cxx_eval_constant_expression (&new_ctx, value, tree elt = cxx_eval_constant_expression (&new_ctx, value,
allow_non_constant, addr, addr,
non_constant_p, overflow_p, non_constant_p, overflow_p,
NULL); NULL);
/* Don't VERIFY_CONSTANT here. */ /* Don't VERIFY_CONSTANT here. */
if (allow_non_constant && *non_constant_p) if (ctx->quiet && *non_constant_p)
break; break;
if (elt != value) if (elt != value)
changed = true; changed = true;
@ -2007,7 +2007,7 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
static tree static tree
cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
bool value_init, bool allow_non_constant, bool addr, bool value_init, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
tree elttype = TREE_TYPE (atype); tree elttype = TREE_TYPE (atype);
@ -2058,7 +2058,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
eltinit = cp_build_array_ref (input_location, init, idx, eltinit = cp_build_array_ref (input_location, init, idx,
tf_warning_or_error); tf_warning_or_error);
eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit, value_init, eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit, value_init,
allow_non_constant, addr, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
} }
else if (pre_init) else if (pre_init)
@ -2066,7 +2066,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
/* Initializing an element using value or default initialization /* Initializing an element using value or default initialization
we just pre-built above. */ we just pre-built above. */
eltinit = (cxx_eval_constant_expression eltinit = (cxx_eval_constant_expression
(&new_ctx, init, allow_non_constant, (&new_ctx, init,
addr, non_constant_p, overflow_p, NULL)); addr, non_constant_p, overflow_p, NULL));
} }
else else
@ -2080,10 +2080,10 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
eltinit = move (eltinit); eltinit = move (eltinit);
eltinit = force_rvalue (eltinit, tf_warning_or_error); eltinit = force_rvalue (eltinit, tf_warning_or_error);
eltinit = (cxx_eval_constant_expression eltinit = (cxx_eval_constant_expression
(&new_ctx, eltinit, allow_non_constant, addr, (&new_ctx, eltinit, addr,
non_constant_p, overflow_p, NULL)); non_constant_p, overflow_p, NULL));
} }
if (*non_constant_p && !allow_non_constant) if (*non_constant_p && !ctx->quiet)
break; break;
if (new_ctx.ctor != ctx->ctor) if (new_ctx.ctor != ctx->ctor)
{ {
@ -2105,14 +2105,14 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
static tree static tree
cxx_eval_vec_init (const constexpr_ctx *ctx, tree t, cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
tree atype = TREE_TYPE (t); tree atype = TREE_TYPE (t);
tree init = VEC_INIT_EXPR_INIT (t); tree init = VEC_INIT_EXPR_INIT (t);
tree r = cxx_eval_vec_init_1 (ctx, atype, init, tree r = cxx_eval_vec_init_1 (ctx, atype, init,
VEC_INIT_EXPR_VALUE_INIT (t), VEC_INIT_EXPR_VALUE_INIT (t),
allow_non_constant, addr, non_constant_p, overflow_p); addr, non_constant_p, overflow_p);
if (*non_constant_p) if (*non_constant_p)
return t; return t;
else else
@ -2312,11 +2312,11 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
static tree static tree
cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
tree orig_op0 = TREE_OPERAND (t, 0); tree orig_op0 = TREE_OPERAND (t, 0);
tree op0 = cxx_eval_constant_expression (ctx, orig_op0, allow_non_constant, tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
/*addr*/false, non_constant_p, /*addr*/false, non_constant_p,
overflow_p, NULL); overflow_p, NULL);
bool empty_base = false; bool empty_base = false;
@ -2330,7 +2330,7 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
&empty_base); &empty_base);
if (r) if (r)
r = cxx_eval_constant_expression (ctx, r, allow_non_constant, r = cxx_eval_constant_expression (ctx, r,
addr, non_constant_p, overflow_p, NULL); addr, non_constant_p, overflow_p, NULL);
else else
{ {
@ -2343,7 +2343,7 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
gcc_assert (!same_type_ignoring_top_level_qualifiers_p gcc_assert (!same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t))); (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
/* DR 1188 says we don't have to deal with this. */ /* DR 1188 says we don't have to deal with this. */
if (!allow_non_constant) if (!ctx->quiet)
error ("accessing value of %qE through a %qT glvalue in a " error ("accessing value of %qE through a %qT glvalue in a "
"constant expression", build_fold_indirect_ref (sub), "constant expression", build_fold_indirect_ref (sub),
TREE_TYPE (t)); TREE_TYPE (t));
@ -2422,7 +2422,7 @@ non_const_var_error (tree r)
static tree static tree
cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t, cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
int i; int i;
@ -2432,7 +2432,7 @@ cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
args[i] = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, i), args[i] = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, i),
allow_non_constant, addr, addr,
non_constant_p, overflow_p, non_constant_p, overflow_p,
NULL); NULL);
VERIFY_CONSTANT (args[i]); VERIFY_CONSTANT (args[i]);
@ -2458,7 +2458,7 @@ var_in_constexpr_fn (tree t)
static tree static tree
cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
constexpr_ctx new_ctx = *ctx; constexpr_ctx new_ctx = *ctx;
@ -2466,7 +2466,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
/* First we figure out where we're storing to. */ /* First we figure out where we're storing to. */
tree target = TREE_OPERAND (t, 0); tree target = TREE_OPERAND (t, 0);
target = cxx_eval_constant_expression (ctx, target, target = cxx_eval_constant_expression (ctx, target,
allow_non_constant, true, true,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
if (*non_constant_p) if (*non_constant_p)
return t; return t;
@ -2499,7 +2499,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
{ {
/* A constant-expression cannot modify objects from outside the /* A constant-expression cannot modify objects from outside the
constant-expression. */ constant-expression. */
if (!allow_non_constant) if (!ctx->quiet)
error ("modification of %qD is not a constant-expression", object); error ("modification of %qD is not a constant-expression", object);
*non_constant_p = true; *non_constant_p = true;
return t; return t;
@ -2542,7 +2542,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
} }
tree init = cxx_eval_constant_expression (&new_ctx, TREE_OPERAND (t, 1), tree init = cxx_eval_constant_expression (&new_ctx, TREE_OPERAND (t, 1),
allow_non_constant, false, false,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
if (target == object) if (target == object)
/* The hash table might have moved since the get earlier. */ /* The hash table might have moved since the get earlier. */
@ -2562,7 +2562,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
static tree static tree
cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t, cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
enum tree_code code = TREE_CODE (t); enum tree_code code = TREE_CODE (t);
@ -2572,12 +2572,12 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
gcc_assert (TREE_CONSTANT (offset)); gcc_assert (TREE_CONSTANT (offset));
/* The operand as an lvalue. */ /* The operand as an lvalue. */
op = cxx_eval_constant_expression (ctx, op, allow_non_constant, true, op = cxx_eval_constant_expression (ctx, op, true,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
/* The operand as an rvalue. */ /* The operand as an rvalue. */
tree val = rvalue (op); tree val = rvalue (op);
val = cxx_eval_constant_expression (ctx, val, allow_non_constant, false, val = cxx_eval_constant_expression (ctx, val, false,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
VERIFY_CONSTANT (val); VERIFY_CONSTANT (val);
@ -2598,7 +2598,7 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
/* Storing the modified value. */ /* Storing the modified value. */
tree store = build2 (MODIFY_EXPR, type, op, mod); tree store = build2 (MODIFY_EXPR, type, op, mod);
cxx_eval_constant_expression (ctx, store, allow_non_constant, cxx_eval_constant_expression (ctx, store,
true, non_constant_p, overflow_p, NULL); true, non_constant_p, overflow_p, NULL);
/* And the value of the expression. */ /* And the value of the expression. */
@ -2686,7 +2686,6 @@ label_matches (tree *jump_target, tree_stmt_iterator i,
static tree static tree
cxx_eval_statement_list (const constexpr_ctx *ctx, tree t, cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
bool allow_non_constant,
bool *non_constant_p, bool *overflow_p, bool *non_constant_p, bool *overflow_p,
tree *jump_target) tree *jump_target)
{ {
@ -2707,7 +2706,7 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
continue; continue;
} }
cxx_eval_constant_expression (ctx, stmt, cxx_eval_constant_expression (ctx, stmt,
allow_non_constant, false, false,
non_constant_p, overflow_p, non_constant_p, overflow_p,
jump_target); jump_target);
if (*non_constant_p) if (*non_constant_p)
@ -2729,14 +2728,13 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
static tree static tree
cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t, cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
bool allow_non_constant,
bool *non_constant_p, bool *overflow_p, bool *non_constant_p, bool *overflow_p,
tree *jump_target) tree *jump_target)
{ {
tree body = TREE_OPERAND (t, 0); tree body = TREE_OPERAND (t, 0);
while (true) while (true)
{ {
cxx_eval_statement_list (ctx, body, allow_non_constant, cxx_eval_statement_list (ctx, body,
non_constant_p, overflow_p, jump_target); non_constant_p, overflow_p, jump_target);
if (returns (jump_target) || breaks (jump_target)) if (returns (jump_target) || breaks (jump_target))
break; break;
@ -2751,18 +2749,17 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
static tree static tree
cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t, cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
bool allow_non_constant,
bool *non_constant_p, bool *overflow_p, bool *non_constant_p, bool *overflow_p,
tree *jump_target) tree *jump_target)
{ {
tree cond = TREE_OPERAND (t, 0); tree cond = TREE_OPERAND (t, 0);
cond = cxx_eval_constant_expression (ctx, cond, allow_non_constant, false, cond = cxx_eval_constant_expression (ctx, cond, false,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
VERIFY_CONSTANT (cond); VERIFY_CONSTANT (cond);
*jump_target = cond; *jump_target = cond;
tree body = TREE_OPERAND (t, 1); tree body = TREE_OPERAND (t, 1);
cxx_eval_statement_list (ctx, body, allow_non_constant, cxx_eval_statement_list (ctx, body,
non_constant_p, overflow_p, jump_target); non_constant_p, overflow_p, jump_target);
if (breaks (jump_target) || switches (jump_target)) if (breaks (jump_target) || switches (jump_target))
*jump_target = NULL_TREE; *jump_target = NULL_TREE;
@ -2776,7 +2773,7 @@ cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
static tree static tree
cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
bool allow_non_constant, bool addr, bool addr,
bool *non_constant_p, bool *overflow_p, bool *non_constant_p, bool *overflow_p,
tree *jump_target) tree *jump_target)
{ {
@ -2792,7 +2789,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
{ {
if (TREE_CODE (t) == PTRMEM_CST) if (TREE_CODE (t) == PTRMEM_CST)
t = cplus_expand_constant (t); t = cplus_expand_constant (t);
else if (TREE_OVERFLOW (t) && (!flag_permissive || allow_non_constant)) else if (TREE_OVERFLOW (t) && (!flag_permissive || ctx->quiet))
*overflow_p = true; *overflow_p = true;
return t; return t;
} }
@ -2824,7 +2821,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
r = *p; r = *p;
if (DECL_P (r)) if (DECL_P (r))
{ {
if (!allow_non_constant) if (!ctx->quiet)
non_const_var_error (r); non_const_var_error (r);
*non_constant_p = true; *non_constant_p = true;
} }
@ -2849,7 +2846,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
/* Defer in case this is only used for its type. */; /* Defer in case this is only used for its type. */;
else else
{ {
if (!allow_non_constant) if (!ctx->quiet)
error ("%qE is not a constant expression", t); error ("%qE is not a constant expression", t);
*non_constant_p = true; *non_constant_p = true;
} }
@ -2857,7 +2854,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case CALL_EXPR: case CALL_EXPR:
case AGGR_INIT_EXPR: case AGGR_INIT_EXPR:
r = cxx_eval_call_expression (ctx, t, allow_non_constant, addr, r = cxx_eval_call_expression (ctx, t, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
@ -2878,7 +2875,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
if (tree init = DECL_INITIAL (r)) if (tree init = DECL_INITIAL (r))
{ {
init = cxx_eval_constant_expression (ctx, init, init = cxx_eval_constant_expression (ctx, init,
allow_non_constant, false, false,
non_constant_p, overflow_p, non_constant_p, overflow_p,
NULL); NULL);
ctx->values->put (r, init); ctx->values->put (r, init);
@ -2893,7 +2890,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case TARGET_EXPR: case TARGET_EXPR:
if (!literal_type_p (TREE_TYPE (t))) if (!literal_type_p (TREE_TYPE (t)))
{ {
if (!allow_non_constant) if (!ctx->quiet)
{ {
error ("temporary of non-literal type %qT in a " error ("temporary of non-literal type %qT in a "
"constant expression", TREE_TYPE (t)); "constant expression", TREE_TYPE (t));
@ -2917,7 +2914,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
/* Pass false for 'addr' because this indicates /* Pass false for 'addr' because this indicates
initialization of a temporary. */ initialization of a temporary. */
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
allow_non_constant, false, false,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
if (!*non_constant_p) if (!*non_constant_p)
/* Adjust the type of the result to the type of the temporary. */ /* Adjust the type of the result to the type of the temporary. */
@ -2930,25 +2927,25 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
/* In C++11 constexpr evaluation we are looking for the value, /* In C++11 constexpr evaluation we are looking for the value,
not the side-effect of the initialization. */ not the side-effect of the initialization. */
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
allow_non_constant, false, false,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
break; break;
} }
/* else fall through */ /* else fall through */
case MODIFY_EXPR: case MODIFY_EXPR:
r = cxx_eval_store_expression (ctx, t, allow_non_constant, addr, r = cxx_eval_store_expression (ctx, t, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
case SCOPE_REF: case SCOPE_REF:
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
allow_non_constant, addr, addr,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
break; break;
case RETURN_EXPR: case RETURN_EXPR:
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
allow_non_constant, addr, addr,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
*jump_target = t; *jump_target = t;
break; break;
@ -2961,7 +2958,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case EXPR_STMT: case EXPR_STMT:
case EH_SPEC_BLOCK: case EH_SPEC_BLOCK:
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
allow_non_constant, addr, addr,
non_constant_p, overflow_p, non_constant_p, overflow_p,
jump_target); jump_target);
break; break;
@ -2970,7 +2967,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
check for a constant operand or result; an address can be check for a constant operand or result; an address can be
constant without its operand being, and vice versa. */ constant without its operand being, and vice versa. */
case INDIRECT_REF: case INDIRECT_REF:
r = cxx_eval_indirect_ref (ctx, t, allow_non_constant, addr, r = cxx_eval_indirect_ref (ctx, t, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
@ -2978,7 +2975,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
{ {
tree oldop = TREE_OPERAND (t, 0); tree oldop = TREE_OPERAND (t, 0);
tree op = cxx_eval_constant_expression (ctx, oldop, tree op = cxx_eval_constant_expression (ctx, oldop,
allow_non_constant,
/*addr*/true, /*addr*/true,
non_constant_p, overflow_p, non_constant_p, overflow_p,
NULL); NULL);
@ -3002,7 +2998,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case BIT_NOT_EXPR: case BIT_NOT_EXPR:
case TRUTH_NOT_EXPR: case TRUTH_NOT_EXPR:
case FIXED_CONVERT_EXPR: case FIXED_CONVERT_EXPR:
r = cxx_eval_unary_expression (ctx, t, allow_non_constant, addr, r = cxx_eval_unary_expression (ctx, t, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
@ -3031,17 +3027,17 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
STRIP_NOPS (op1); STRIP_NOPS (op1);
if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0)) if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
|| TREE_CODE (op1) == EMPTY_CLASS_EXPR) || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
r = cxx_eval_constant_expression (ctx, op0, allow_non_constant, r = cxx_eval_constant_expression (ctx, op0,
addr, non_constant_p, overflow_p, addr, non_constant_p, overflow_p,
jump_target); jump_target);
else else
{ {
/* Check that the LHS is constant and then discard it. */ /* Check that the LHS is constant and then discard it. */
cxx_eval_constant_expression (ctx, op0, allow_non_constant, cxx_eval_constant_expression (ctx, op0,
false, non_constant_p, overflow_p, false, non_constant_p, overflow_p,
jump_target); jump_target);
op1 = TREE_OPERAND (t, 1); op1 = TREE_OPERAND (t, 1);
r = cxx_eval_constant_expression (ctx, op1, allow_non_constant, r = cxx_eval_constant_expression (ctx, op1,
addr, non_constant_p, overflow_p, addr, non_constant_p, overflow_p,
jump_target); jump_target);
} }
@ -3087,7 +3083,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case LTGT_EXPR: case LTGT_EXPR:
case RANGE_EXPR: case RANGE_EXPR:
case COMPLEX_EXPR: case COMPLEX_EXPR:
r = cxx_eval_binary_expression (ctx, t, allow_non_constant, addr, r = cxx_eval_binary_expression (ctx, t, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
@ -3097,7 +3093,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case TRUTH_ANDIF_EXPR: case TRUTH_ANDIF_EXPR:
r = cxx_eval_logical_expression (ctx, t, boolean_false_node, r = cxx_eval_logical_expression (ctx, t, boolean_false_node,
boolean_true_node, boolean_true_node,
allow_non_constant, addr, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
@ -3105,12 +3101,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case TRUTH_ORIF_EXPR: case TRUTH_ORIF_EXPR:
r = cxx_eval_logical_expression (ctx, t, boolean_true_node, r = cxx_eval_logical_expression (ctx, t, boolean_true_node,
boolean_false_node, boolean_false_node,
allow_non_constant, addr, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
case ARRAY_REF: case ARRAY_REF:
r = cxx_eval_array_reference (ctx, t, allow_non_constant, addr, r = cxx_eval_array_reference (ctx, t, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
@ -3121,28 +3117,28 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
build_non_dependent_expr, because any expression that build_non_dependent_expr, because any expression that
calls or takes the address of the function will have calls or takes the address of the function will have
pulled a FUNCTION_DECL out of the COMPONENT_REF. */ pulled a FUNCTION_DECL out of the COMPONENT_REF. */
gcc_checking_assert (allow_non_constant || errorcount); gcc_checking_assert (ctx->quiet || errorcount);
*non_constant_p = true; *non_constant_p = true;
return t; return t;
} }
r = cxx_eval_component_reference (ctx, t, allow_non_constant, addr, r = cxx_eval_component_reference (ctx, t, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
case BIT_FIELD_REF: case BIT_FIELD_REF:
r = cxx_eval_bit_field_ref (ctx, t, allow_non_constant, addr, r = cxx_eval_bit_field_ref (ctx, t, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
case COND_EXPR: case COND_EXPR:
case VEC_COND_EXPR: case VEC_COND_EXPR:
r = cxx_eval_conditional_expression (ctx, t, allow_non_constant, addr, r = cxx_eval_conditional_expression (ctx, t, addr,
non_constant_p, overflow_p, non_constant_p, overflow_p,
jump_target); jump_target);
break; break;
case CONSTRUCTOR: case CONSTRUCTOR:
r = cxx_eval_bare_aggregate (ctx, t, allow_non_constant, addr, r = cxx_eval_bare_aggregate (ctx, t, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
@ -3152,13 +3148,13 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
be NULL, meaning default-initialization, or it will be an lvalue be NULL, meaning default-initialization, or it will be an lvalue
or xvalue of the same type, meaning direct-initialization from the or xvalue of the same type, meaning direct-initialization from the
corresponding member. */ corresponding member. */
r = cxx_eval_vec_init (ctx, t, allow_non_constant, addr, r = cxx_eval_vec_init (ctx, t, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
case FMA_EXPR: case FMA_EXPR:
case VEC_PERM_EXPR: case VEC_PERM_EXPR:
r = cxx_eval_trinary_expression (ctx, t, allow_non_constant, addr, r = cxx_eval_trinary_expression (ctx, t, addr,
non_constant_p, overflow_p); non_constant_p, overflow_p);
break; break;
@ -3168,7 +3164,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
{ {
tree oldop = TREE_OPERAND (t, 0); tree oldop = TREE_OPERAND (t, 0);
tree op = cxx_eval_constant_expression (ctx, oldop, tree op = cxx_eval_constant_expression (ctx, oldop,
allow_non_constant, addr, addr,
non_constant_p, overflow_p, non_constant_p, overflow_p,
NULL); NULL);
if (*non_constant_p) if (*non_constant_p)
@ -3177,7 +3173,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
&& TREE_CODE (op) == INTEGER_CST && TREE_CODE (op) == INTEGER_CST
&& !integer_zerop (op)) && !integer_zerop (op))
{ {
if (!allow_non_constant) if (!ctx->quiet)
error_at (EXPR_LOC_OR_LOC (t, input_location), error_at (EXPR_LOC_OR_LOC (t, input_location),
"reinterpret_cast from integer to pointer"); "reinterpret_cast from integer to pointer");
*non_constant_p = true; *non_constant_p = true;
@ -3204,12 +3200,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case STATEMENT_LIST: case STATEMENT_LIST:
new_ctx = *ctx; new_ctx = *ctx;
new_ctx.ctor = new_ctx.object = NULL_TREE; new_ctx.ctor = new_ctx.object = NULL_TREE;
return cxx_eval_statement_list (&new_ctx, t, allow_non_constant, return cxx_eval_statement_list (&new_ctx, t,
non_constant_p, overflow_p, jump_target); non_constant_p, overflow_p, jump_target);
case BIND_EXPR: case BIND_EXPR:
return cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (t), return cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (t),
allow_non_constant, addr, addr,
non_constant_p, overflow_p, non_constant_p, overflow_p,
jump_target); jump_target);
@ -3217,7 +3213,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case POSTINCREMENT_EXPR: case POSTINCREMENT_EXPR:
case PREDECREMENT_EXPR: case PREDECREMENT_EXPR:
case POSTDECREMENT_EXPR: case POSTDECREMENT_EXPR:
return cxx_eval_increment_expression (ctx, t, allow_non_constant, return cxx_eval_increment_expression (ctx, t,
addr, non_constant_p, overflow_p); addr, non_constant_p, overflow_p);
case LAMBDA_EXPR: case LAMBDA_EXPR:
@ -3234,7 +3230,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case NON_DEPENDENT_EXPR: case NON_DEPENDENT_EXPR:
case BASELINK: case BASELINK:
case OFFSET_REF: case OFFSET_REF:
if (!allow_non_constant) if (!ctx->quiet)
error_at (EXPR_LOC_OR_LOC (t, input_location), error_at (EXPR_LOC_OR_LOC (t, input_location),
"expression %qE is not a constant-expression", t); "expression %qE is not a constant-expression", t);
*non_constant_p = true; *non_constant_p = true;
@ -3246,7 +3242,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
/* A placeholder without a referent. We can get here when /* A placeholder without a referent. We can get here when
checking whether NSDMIs are noexcept, or in massage_init_elt; checking whether NSDMIs are noexcept, or in massage_init_elt;
just say it's non-constant for now. */ just say it's non-constant for now. */
gcc_assert (allow_non_constant); gcc_assert (ctx->quiet);
*non_constant_p = true; *non_constant_p = true;
break; break;
} }
@ -3259,7 +3255,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
gcc_assert (same_type_ignoring_top_level_qualifiers_p gcc_assert (same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (t), TREE_TYPE (ctor))); (TREE_TYPE (t), TREE_TYPE (ctor)));
return cxx_eval_constant_expression return cxx_eval_constant_expression
(ctx, ctor, allow_non_constant, addr, (ctx, ctor, addr,
non_constant_p, overflow_p, NULL); non_constant_p, overflow_p, NULL);
} }
break; break;
@ -3270,12 +3266,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
break; break;
case LOOP_EXPR: case LOOP_EXPR:
cxx_eval_loop_expr (ctx, t, allow_non_constant, cxx_eval_loop_expr (ctx, t,
non_constant_p, overflow_p, jump_target); non_constant_p, overflow_p, jump_target);
break; break;
case SWITCH_EXPR: case SWITCH_EXPR:
cxx_eval_switch_expr (ctx, t, allow_non_constant, cxx_eval_switch_expr (ctx, t,
non_constant_p, overflow_p, jump_target); non_constant_p, overflow_p, jump_target);
break; break;
@ -3301,7 +3297,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
{ {
bool non_constant_p = false; bool non_constant_p = false;
bool overflow_p = false; bool overflow_p = false;
constexpr_ctx ctx = { NULL, NULL, NULL, NULL }; constexpr_ctx ctx = { NULL, NULL, NULL, NULL, allow_non_constant };
hash_map<tree,tree> map; hash_map<tree,tree> map;
ctx.values = &map; ctx.values = &map;
tree type = initialized_type (t); tree type = initialized_type (t);
@ -3336,7 +3332,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
r = TARGET_EXPR_INITIAL (r); r = TARGET_EXPR_INITIAL (r);
} }
r = cxx_eval_constant_expression (&ctx, r, allow_non_constant, r = cxx_eval_constant_expression (&ctx, r,
false, &non_constant_p, &overflow_p, NULL); false, &non_constant_p, &overflow_p, NULL);
verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p); verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
@ -3410,10 +3406,10 @@ is_sub_constant_expr (tree t)
{ {
bool non_constant_p = false; bool non_constant_p = false;
bool overflow_p = false; bool overflow_p = false;
constexpr_ctx ctx = { NULL, NULL, NULL, NULL }; constexpr_ctx ctx = { NULL, NULL, NULL, NULL, true };
hash_map <tree, tree> map; hash_map <tree, tree> map;
ctx.values = &map; ctx.values = &map;
cxx_eval_constant_expression (&ctx, t, true, false, &non_constant_p, cxx_eval_constant_expression (&ctx, t, false, &non_constant_p,
&overflow_p, NULL); &overflow_p, NULL);
return !non_constant_p && !overflow_p; return !non_constant_p && !overflow_p;
} }