semantics.c (end_maybe_infinite_loop): Use fold_non_dependent_expr.

2014-11-14  Paolo Carlini  <paolo.carlini@oracle.com>

	* semantics.c (end_maybe_infinite_loop): Use fold_non_dependent_expr.
	* parser.c (cp_parser_omp_clause_collapse): Likewise.
	(cp_parser_enumerator_definition): Don't call
	instantiate_non_dependent_expr...
	* decl.c (build_enumerator): ... call fold_non_dependent_expr here.
	* typeck2.c (massage_init_elt): Use fold_non_dependent_expr.
	* constexpr.c (maybe_constant_value): Allow VIEW_CONVERT_EXPR in
	the final gcc_assert.

	* constexpr.c (fold_non_dependent_expr): Add.
	* cp-tree.h (fold_non_dependent_expr): Declare it.
	* call.c (null_ptr_cst_p): Use it.
	* pt.c (tsubst_copy_and_build, build_non_dependent_expr): Likewise.
	* semantics.c (begin_maybe_infinite_loop): Likewise.
	* typeck.c (cp_build_binary_op): Likewise.
	* typeck2.c (check_narrowing): Likewise.

	* pt.c (fold_non_dependent_expr): Rename to
	instantiate_non_dependent_expr.
	(fold_non_dependent_expr_sfinae): Rename to
	instantiate_non_dependent_expr_sfinae.
	(convert_nontype_argument, build_non_dependent_expr): Adjust.
	* decl.c (compute_array_index_type): Likewise.
	* parser.c (cp_parser_parenthesized_expression_list,
	cp_parser_enumerator_definition, cp_parser_omp_clause_collapse):
	Likewise.
	* semantics.c (end_maybe_infinite_loop, finish_static_assert):
	Likewise.
	* typeck.c (cxx_alignas_expr): Likewise.
	* typeck2.c (store_init_value, massage_init_elt): Likewise.
	* call.c: Adjust comments.
	* class.c: Likewise.
	* constexpr.c: Likewise.
	* decl2.c: Likewise.
	* tree.c: Likewise.

From-SVN: r217577
This commit is contained in:
Paolo Carlini 2014-11-14 16:59:52 +00:00 committed by Paolo Carlini
parent 2c59c2d1a2
commit 234bef96a1
13 changed files with 151 additions and 48 deletions

View file

@ -1,3 +1,41 @@
2014-11-14 Paolo Carlini <paolo.carlini@oracle.com>
* semantics.c (end_maybe_infinite_loop): Use fold_non_dependent_expr.
* parser.c (cp_parser_omp_clause_collapse): Likewise.
(cp_parser_enumerator_definition): Don't call
instantiate_non_dependent_expr...
* decl.c (build_enumerator): ... call fold_non_dependent_expr here.
* typeck2.c (massage_init_elt): Use fold_non_dependent_expr.
* constexpr.c (maybe_constant_value): Allow VIEW_CONVERT_EXPR in
the final gcc_assert.
* constexpr.c (fold_non_dependent_expr): Add.
* cp-tree.h (fold_non_dependent_expr): Declare it.
* call.c (null_ptr_cst_p): Use it.
* pt.c (tsubst_copy_and_build, build_non_dependent_expr): Likewise.
* semantics.c (begin_maybe_infinite_loop): Likewise.
* typeck.c (cp_build_binary_op): Likewise.
* typeck2.c (check_narrowing): Likewise.
* pt.c (fold_non_dependent_expr): Rename to
instantiate_non_dependent_expr.
(fold_non_dependent_expr_sfinae): Rename to
instantiate_non_dependent_expr_sfinae.
(convert_nontype_argument, build_non_dependent_expr): Adjust.
* decl.c (compute_array_index_type): Likewise.
* parser.c (cp_parser_parenthesized_expression_list,
cp_parser_enumerator_definition, cp_parser_omp_clause_collapse):
Likewise.
* semantics.c (end_maybe_infinite_loop, finish_static_assert):
Likewise.
* typeck.c (cxx_alignas_expr): Likewise.
* typeck2.c (store_init_value, massage_init_elt): Likewise.
* call.c: Adjust comments.
* class.c: Likewise.
* constexpr.c: Likewise.
* decl2.c: Likewise.
* tree.c: Likewise.
2014-11-14 Jonathan Wakely <jwakely@redhat.com> 2014-11-14 Jonathan Wakely <jwakely@redhat.com>
* mangle.c (find_substitution): Look for abi_tag on class templates. * mangle.c (find_substitution): Look for abi_tag on class templates.

View file

@ -572,7 +572,7 @@ null_ptr_cst_p (tree t)
{ {
/* Core issue 903 says only literal 0 is a null pointer constant. */ /* Core issue 903 says only literal 0 is a null pointer constant. */
if (cxx_dialect < cxx11) if (cxx_dialect < cxx11)
t = maybe_constant_value (fold_non_dependent_expr_sfinae (t, tf_none)); t = fold_non_dependent_expr (t);
STRIP_NOPS (t); STRIP_NOPS (t);
if (integer_zerop (t) && !TREE_OVERFLOW (t)) if (integer_zerop (t) && !TREE_OVERFLOW (t))
return true; return true;
@ -7437,8 +7437,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
return error_mark_node; return error_mark_node;
if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0 if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
/* Don't mess with virtual lookup in fold_non_dependent_expr; virtual /* Don't mess with virtual lookup in instantiate_non_dependent_expr;
functions can't be constexpr. */ virtual functions can't be constexpr. */
&& !in_template_function ()) && !in_template_function ())
{ {
tree t; tree t;
@ -9361,7 +9361,7 @@ perform_implicit_conversion_flags (tree type, tree expr,
type of non-dependent expressions, so we do not have to type of non-dependent expressions, so we do not have to
perform the actual conversion. But for initializers, we perform the actual conversion. But for initializers, we
need to be able to perform it at instantiation need to be able to perform it at instantiation
(or fold_non_dependent_expr) time. */ (or instantiate_non_dependent_expr) time. */
expr = build1 (IMPLICIT_CONV_EXPR, type, expr); expr = build1 (IMPLICIT_CONV_EXPR, type, expr);
if (!(flags & LOOKUP_ONLYCONVERTING)) if (!(flags & LOOKUP_ONLYCONVERTING))
IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true; IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true;

View file

@ -359,9 +359,9 @@ build_base_path (enum tree_code code,
/* Don't bother with the calculations inside sizeof; they'll ICE if the /* Don't bother with the calculations inside sizeof; they'll ICE if the
source type is incomplete and the pointer value doesn't matter. In a source type is incomplete and the pointer value doesn't matter. In a
template (even in fold_non_dependent_expr), we don't have vtables set template (even in instantiate_non_dependent_expr), we don't have vtables
up properly yet, and the value doesn't matter there either; we're just set up properly yet, and the value doesn't matter there either; we're
interested in the result of overload resolution. */ just interested in the result of overload resolution. */
if (cp_unevaluated_operand != 0 if (cp_unevaluated_operand != 0
|| in_template_function ()) || in_template_function ())
{ {
@ -6933,7 +6933,8 @@ resolves_to_fixed_type_p (tree instance, int* nonnull)
tree fixed; tree fixed;
/* processing_template_decl can be false in a template if we're in /* processing_template_decl can be false in a template if we're in
fold_non_dependent_expr, but we still want to suppress this check. */ instantiate_non_dependent_expr, but we still want to suppress
this check. */
if (in_template_function ()) if (in_template_function ())
{ {
/* In a template we only care about the type of the result. */ /* In a template we only care about the type of the result. */

View file

@ -2908,12 +2908,83 @@ maybe_constant_value (tree t, tree decl)
/* cp_tree_equal looks through NOPs, so allow them. */ /* cp_tree_equal looks through NOPs, so allow them. */
gcc_assert (r == t gcc_assert (r == t
|| CONVERT_EXPR_P (t) || CONVERT_EXPR_P (t)
|| TREE_CODE (t) == VIEW_CONVERT_EXPR
|| (TREE_CONSTANT (t) && !TREE_CONSTANT (r)) || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
|| !cp_tree_equal (r, t)); || !cp_tree_equal (r, t));
#endif #endif
return r; return r;
} }
/* Like maybe_constant_value but first fully instantiate the argument.
Note: this is equivalent to instantiate_non_dependent_expr_sfinae
(t, tf_none) followed by maybe_constant_value but is more efficient,
because calls instantiation_dependent_expression_p and
potential_constant_expression at most once. */
tree
fold_non_dependent_expr (tree t)
{
if (t == NULL_TREE)
return NULL_TREE;
/* If we're in a template, but T isn't value dependent, simplify
it. We're supposed to treat:
template <typename T> void f(T[1 + 1]);
template <typename T> void f(T[2]);
as two declarations of the same function, for example. */
if (processing_template_decl)
{
if (!instantiation_dependent_expression_p (t)
&& potential_constant_expression (t))
{
HOST_WIDE_INT saved_processing_template_decl;
saved_processing_template_decl = processing_template_decl;
processing_template_decl = 0;
t = tsubst_copy_and_build (t,
/*args=*/NULL_TREE,
tf_none,
/*in_decl=*/NULL_TREE,
/*function_p=*/false,
/*integral_constant_expression_p=*/true);
processing_template_decl = saved_processing_template_decl;
if (type_unknown_p (t)
|| BRACE_ENCLOSED_INITIALIZER_P (t))
{
if (TREE_OVERFLOW_P (t))
{
t = build_nop (TREE_TYPE (t), t);
TREE_CONSTANT (t) = false;
}
return t;
}
tree r = cxx_eval_outermost_constant_expr (t, true, NULL_TREE);
#ifdef ENABLE_CHECKING
/* cp_tree_equal looks through NOPs, so allow them. */
gcc_assert (r == t
|| CONVERT_EXPR_P (t)
|| TREE_CODE (t) == VIEW_CONVERT_EXPR
|| (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
|| !cp_tree_equal (r, t));
#endif
return r;
}
else if (TREE_OVERFLOW_P (t))
{
t = build_nop (TREE_TYPE (t), t);
TREE_CONSTANT (t) = false;
}
return t;
}
return maybe_constant_value (t);
}
/* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather /* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather
than wrapped in a TARGET_EXPR. */ than wrapped in a TARGET_EXPR. */
@ -3386,7 +3457,7 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
if (!potential_constant_expression_1 (denom, rval, flags)) if (!potential_constant_expression_1 (denom, rval, flags))
return false; return false;
/* We can't call cxx_eval_outermost_constant_expr on an expression /* We can't call cxx_eval_outermost_constant_expr on an expression
that hasn't been through fold_non_dependent_expr yet. */ that hasn't been through instantiate_non_dependent_expr yet. */
if (!processing_template_decl) if (!processing_template_decl)
denom = cxx_eval_outermost_constant_expr (denom, true); denom = cxx_eval_outermost_constant_expr (denom, true);
if (integer_zerop (denom)) if (integer_zerop (denom))

View file

@ -5690,8 +5690,8 @@ extern tree template_for_substitution (tree);
extern tree build_non_dependent_expr (tree); extern tree build_non_dependent_expr (tree);
extern void make_args_non_dependent (vec<tree, va_gc> *); extern void make_args_non_dependent (vec<tree, va_gc> *);
extern bool reregister_specialization (tree, tree, tree); extern bool reregister_specialization (tree, tree, tree);
extern tree fold_non_dependent_expr (tree); extern tree instantiate_non_dependent_expr (tree);
extern tree fold_non_dependent_expr_sfinae (tree, tsubst_flags_t); extern tree instantiate_non_dependent_expr_sfinae (tree, tsubst_flags_t);
extern bool alias_type_or_template_p (tree); extern bool alias_type_or_template_p (tree);
extern bool alias_template_specialization_p (const_tree); extern bool alias_template_specialization_p (const_tree);
extern bool dependent_alias_template_spec_p (const_tree); extern bool dependent_alias_template_spec_p (const_tree);
@ -6331,6 +6331,7 @@ extern bool require_potential_rvalue_constant_expression (tree);
extern tree cxx_constant_value (tree, tree = NULL_TREE); extern tree cxx_constant_value (tree, tree = NULL_TREE);
extern tree maybe_constant_value (tree, tree = NULL_TREE); extern tree maybe_constant_value (tree, tree = NULL_TREE);
extern tree maybe_constant_init (tree, tree = NULL_TREE); extern tree maybe_constant_init (tree, tree = NULL_TREE);
extern tree fold_non_dependent_expr (tree);
extern bool is_sub_constant_expr (tree); extern bool is_sub_constant_expr (tree);
extern bool reduced_constant_expression_p (tree); extern bool reduced_constant_expression_p (tree);
extern bool is_instantiation_of_constexpr (tree); extern bool is_instantiation_of_constexpr (tree);

View file

@ -8356,7 +8356,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
NOP_EXPR with TREE_SIDE_EFFECTS; don't fold in that case. */; NOP_EXPR with TREE_SIDE_EFFECTS; don't fold in that case. */;
else else
{ {
size = fold_non_dependent_expr_sfinae (size, complain); size = instantiate_non_dependent_expr_sfinae (size, complain);
if (CLASS_TYPE_P (type) if (CLASS_TYPE_P (type)
&& CLASSTYPE_LITERAL_P (type)) && CLASSTYPE_LITERAL_P (type))
@ -12999,6 +12999,11 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc)
tree context; tree context;
tree type; tree type;
/* integral_constant_value will pull out this expression, so make sure
it's folded as appropriate. */
if (processing_template_decl)
value = fold_non_dependent_expr (value);
/* If the VALUE was erroneous, pretend it wasn't there; that will /* If the VALUE was erroneous, pretend it wasn't there; that will
result in the enum being assigned the next value in sequence. */ result in the enum being assigned the next value in sequence. */
if (value == error_mark_node) if (value == error_mark_node)

View file

@ -4951,7 +4951,7 @@ mark_used (tree decl, tsubst_flags_t complain)
if (processing_template_decl) if (processing_template_decl)
return true; return true;
/* Check this too in case we're within fold_non_dependent_expr. */ /* Check this too in case we're within instantiate_non_dependent_expr. */
if (DECL_TEMPLATE_INFO (decl) if (DECL_TEMPLATE_INFO (decl)
&& uses_template_parms (DECL_TI_ARGS (decl))) && uses_template_parms (DECL_TI_ARGS (decl)))
return true; return true;

View file

@ -6886,7 +6886,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
} }
if (fold_expr_p) if (fold_expr_p)
expr = fold_non_dependent_expr (expr); expr = instantiate_non_dependent_expr (expr);
/* If we have an ellipsis, then this is an expression /* If we have an ellipsis, then this is an expression
expansion. */ expansion. */
@ -15996,10 +15996,6 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type)
if (check_for_bare_parameter_packs (value)) if (check_for_bare_parameter_packs (value))
value = error_mark_node; value = error_mark_node;
/* integral_constant_value will pull out this expression, so make sure
it's folded as appropriate. */
value = fold_non_dependent_expr (value);
/* Create the enumerator. */ /* Create the enumerator. */
build_enumerator (identifier, value, type, loc); build_enumerator (identifier, value, type, loc);
} }

View file

@ -5216,7 +5216,7 @@ redeclare_class_template (tree type, tree parms)
(possibly simplified) expression. */ (possibly simplified) expression. */
tree tree
fold_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain) instantiate_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain)
{ {
if (expr == NULL_TREE) if (expr == NULL_TREE)
return NULL_TREE; return NULL_TREE;
@ -5248,9 +5248,9 @@ fold_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain)
} }
tree tree
fold_non_dependent_expr (tree expr) instantiate_non_dependent_expr (tree expr)
{ {
return fold_non_dependent_expr_sfinae (expr, tf_error); return instantiate_non_dependent_expr_sfinae (expr, tf_error);
} }
/* Return TRUE iff T is a type alias, a TEMPLATE_DECL for an alias /* Return TRUE iff T is a type alias, a TEMPLATE_DECL for an alias
@ -5740,7 +5740,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
&& has_value_dependent_address (expr)) && has_value_dependent_address (expr))
/* If we want the address and it's value-dependent, don't fold. */; /* If we want the address and it's value-dependent, don't fold. */;
else if (!type_unknown_p (expr)) else if (!type_unknown_p (expr))
expr = fold_non_dependent_expr_sfinae (expr, complain); expr = instantiate_non_dependent_expr_sfinae (expr, complain);
if (error_operand_p (expr)) if (error_operand_p (expr))
return error_mark_node; return error_mark_node;
expr_type = TREE_TYPE (expr); expr_type = TREE_TYPE (expr);
@ -8314,7 +8314,7 @@ uses_template_parms (tree t)
/* Returns true iff current_function_decl is an incompletely instantiated /* Returns true iff current_function_decl is an incompletely instantiated
template. Useful instead of processing_template_decl because the latter template. Useful instead of processing_template_decl because the latter
is set to 0 during fold_non_dependent_expr. */ is set to 0 during instantiate_non_dependent_expr. */
bool bool
in_template_function (void) in_template_function (void)
@ -15138,8 +15138,7 @@ tsubst_copy_and_build (tree t,
case COND_EXPR: case COND_EXPR:
{ {
tree cond = RECUR (TREE_OPERAND (t, 0)); tree cond = RECUR (TREE_OPERAND (t, 0));
tree folded_cond = (maybe_constant_value tree folded_cond = fold_non_dependent_expr (cond);
(fold_non_dependent_expr_sfinae (cond, tf_none)));
tree exp1, exp2; tree exp1, exp2;
if (TREE_CODE (folded_cond) == INTEGER_CST) if (TREE_CODE (folded_cond) == INTEGER_CST)
@ -21110,7 +21109,7 @@ value_dependent_expression_p (tree expression)
case STMT_EXPR: case STMT_EXPR:
/* Treat a GNU statement expression as dependent to avoid crashing /* Treat a GNU statement expression as dependent to avoid crashing
under fold_non_dependent_expr; it can't be constant. */ under instantiate_non_dependent_expr; it can't be constant. */
return true; return true;
default: default:
@ -21864,7 +21863,7 @@ build_non_dependent_expr (tree expr)
/* Try to get a constant value for all non-dependent expressions in /* Try to get a constant value for all non-dependent expressions in
order to expose bugs in *_dependent_expression_p and constexpr. */ order to expose bugs in *_dependent_expression_p and constexpr. */
if (cxx_dialect >= cxx11) if (cxx_dialect >= cxx11)
maybe_constant_value (fold_non_dependent_expr_sfinae (expr, tf_none)); fold_non_dependent_expr (expr);
#endif #endif
/* Preserve OVERLOADs; the functions must be available to resolve /* Preserve OVERLOADs; the functions must be available to resolve

View file

@ -511,8 +511,7 @@ begin_maybe_infinite_loop (tree cond)
bool maybe_infinite = true; bool maybe_infinite = true;
if (cond) if (cond)
{ {
cond = fold_non_dependent_expr_sfinae (cond, tf_none); cond = fold_non_dependent_expr (cond);
cond = maybe_constant_value (cond);
maybe_infinite = integer_nonzerop (cond); maybe_infinite = integer_nonzerop (cond);
} }
vec_safe_push (cp_function_chain->infinite_loops, vec_safe_push (cp_function_chain->infinite_loops,
@ -543,7 +542,6 @@ end_maybe_infinite_loop (tree cond)
if (current != NULL_TREE) if (current != NULL_TREE)
{ {
cond = fold_non_dependent_expr (cond); cond = fold_non_dependent_expr (cond);
cond = maybe_constant_value (cond);
if (integer_nonzerop (cond)) if (integer_nonzerop (cond))
current_function_infinite_loop = 1; current_function_infinite_loop = 1;
} }
@ -7043,7 +7041,7 @@ finish_static_assert (tree condition, tree message, location_t location,
} }
/* Fold the expression and convert it to a boolean value. */ /* Fold the expression and convert it to a boolean value. */
condition = fold_non_dependent_expr (condition); condition = instantiate_non_dependent_expr (condition);
condition = cp_convert (boolean_type_node, condition, tf_warning_or_error); condition = cp_convert (boolean_type_node, condition, tf_warning_or_error);
condition = maybe_constant_value (condition); condition = maybe_constant_value (condition);

View file

@ -4143,7 +4143,7 @@ fold_if_not_in_template (tree expr)
/* In the body of a template, there is never any need to call /* In the body of a template, there is never any need to call
"fold". We will call fold later when actually instantiating the "fold". We will call fold later when actually instantiating the
template. Integral constant expressions in templates will be template. Integral constant expressions in templates will be
evaluated via fold_non_dependent_expr, as necessary. */ evaluated via instantiate_non_dependent_expr, as necessary. */
if (processing_template_decl) if (processing_template_decl)
return expr; return expr;

View file

@ -1787,7 +1787,7 @@ cxx_alignas_expr (tree e)
/* Leave value-dependent expression alone for now. */ /* Leave value-dependent expression alone for now. */
return e; return e;
e = fold_non_dependent_expr (e); e = instantiate_non_dependent_expr (e);
e = mark_rvalue_use (e); e = mark_rvalue_use (e);
/* [dcl.align]/2 says: /* [dcl.align]/2 says:
@ -4135,8 +4135,7 @@ cp_build_binary_op (location_t location,
|| code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)) || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
{ {
enum tree_code tcode0 = code0, tcode1 = code1; enum tree_code tcode0 = code0, tcode1 = code1;
tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none); tree cop1 = fold_non_dependent_expr (op1);
cop1 = maybe_constant_value (cop1);
doing_div_or_mod = true; doing_div_or_mod = true;
warn_for_div_by_zero (location, cop1); warn_for_div_by_zero (location, cop1);
@ -4175,8 +4174,7 @@ cp_build_binary_op (location_t location,
case TRUNC_MOD_EXPR: case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR: case FLOOR_MOD_EXPR:
{ {
tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none); tree cop1 = fold_non_dependent_expr (op1);
cop1 = maybe_constant_value (cop1);
doing_div_or_mod = true; doing_div_or_mod = true;
warn_for_div_by_zero (location, cop1); warn_for_div_by_zero (location, cop1);
} }
@ -4270,8 +4268,7 @@ cp_build_binary_op (location_t location,
} }
else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{ {
tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none); tree const_op1 = fold_non_dependent_expr (op1);
const_op1 = maybe_constant_value (const_op1);
if (TREE_CODE (const_op1) != INTEGER_CST) if (TREE_CODE (const_op1) != INTEGER_CST)
const_op1 = op1; const_op1 = op1;
result_type = type0; result_type = type0;
@ -4320,8 +4317,7 @@ cp_build_binary_op (location_t location,
} }
else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{ {
tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none); tree const_op1 = fold_non_dependent_expr (op1);
const_op1 = maybe_constant_value (const_op1);
if (TREE_CODE (const_op1) != INTEGER_CST) if (TREE_CODE (const_op1) != INTEGER_CST)
const_op1 = op1; const_op1 = op1;
result_type = type0; result_type = type0;
@ -4993,10 +4989,8 @@ cp_build_binary_op (location_t location,
/* OP0 and/or OP1 might have side-effects. */ /* OP0 and/or OP1 might have side-effects. */
op0 = cp_save_expr (op0); op0 = cp_save_expr (op0);
op1 = cp_save_expr (op1); op1 = cp_save_expr (op1);
op0 = maybe_constant_value (fold_non_dependent_expr_sfinae (op0, op0 = fold_non_dependent_expr (op0);
tf_none)); op1 = fold_non_dependent_expr (op1);
op1 = maybe_constant_value (fold_non_dependent_expr_sfinae (op1,
tf_none));
if (doing_div_or_mod && (flag_sanitize & (SANITIZE_DIVIDE if (doing_div_or_mod && (flag_sanitize & (SANITIZE_DIVIDE
| SANITIZE_FLOAT_DIVIDE))) | SANITIZE_FLOAT_DIVIDE)))
{ {

View file

@ -797,7 +797,7 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
if (decl_maybe_constant_var_p (decl) || TREE_STATIC (decl)) if (decl_maybe_constant_var_p (decl) || TREE_STATIC (decl))
{ {
bool const_init; bool const_init;
value = fold_non_dependent_expr (value); value = instantiate_non_dependent_expr (value);
if (DECL_DECLARED_CONSTEXPR_P (decl) if (DECL_DECLARED_CONSTEXPR_P (decl)
|| DECL_IN_AGGR_P (decl)) || DECL_IN_AGGR_P (decl))
{ {
@ -872,7 +872,7 @@ check_narrowing (tree type, tree init, tsubst_flags_t complain)
return ok; return ok;
} }
init = maybe_constant_value (fold_non_dependent_expr_sfinae (init, tf_none)); init = fold_non_dependent_expr (init);
if (TREE_CODE (type) == INTEGER_TYPE if (TREE_CODE (type) == INTEGER_TYPE
&& TREE_CODE (ftype) == REAL_TYPE) && TREE_CODE (ftype) == REAL_TYPE)
@ -1176,7 +1176,7 @@ massage_init_elt (tree type, tree init, tsubst_flags_t complain)
init = TARGET_EXPR_INITIAL (init); init = TARGET_EXPR_INITIAL (init);
/* When we defer constant folding within a statement, we may want to /* When we defer constant folding within a statement, we may want to
defer this folding as well. */ defer this folding as well. */
tree t = fold_non_dependent_expr_sfinae (init, complain); tree t = fold_non_dependent_expr (init);
t = maybe_constant_init (t); t = maybe_constant_init (t);
if (TREE_CONSTANT (t)) if (TREE_CONSTANT (t))
init = t; init = t;