Hi, shall we do something like the below? Safety checked x86_64-linux.
Thanks, Paolo. ///////////////////
2014-11-13 Paolo Carlini <paolo.carl...@oracle.com> * constexpr.c (maybe_constant_folded_value): Add. * cp-tree.h (maybe_constant_folded_value): 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.
Index: call.c =================================================================== --- call.c (revision 217468) +++ call.c (working copy) @@ -572,7 +572,7 @@ null_ptr_cst_p (tree t) { /* Core issue 903 says only literal 0 is a null pointer constant. */ if (cxx_dialect < cxx11) - t = maybe_constant_value (fold_non_dependent_expr_sfinae (t, tf_none)); + t = maybe_constant_folded_value (t); STRIP_NOPS (t); if (integer_zerop (t) && !TREE_OVERFLOW (t)) return true; Index: constexpr.c =================================================================== --- constexpr.c (revision 217468) +++ constexpr.c (working copy) @@ -2914,6 +2914,14 @@ maybe_constant_value (tree t, tree decl) return r; } +/* Like maybe_constant_value but first fold the argument. */ + +tree +maybe_constant_folded_value (tree t) +{ + return maybe_constant_value (fold_non_dependent_expr_sfinae (t, tf_none)); +} + /* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather than wrapped in a TARGET_EXPR. */ Index: cp-tree.h =================================================================== --- cp-tree.h (revision 217468) +++ cp-tree.h (working copy) @@ -6334,6 +6334,7 @@ extern bool require_potential_rvalue_constant_expr extern tree cxx_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_folded_value (tree); extern bool is_sub_constant_expr (tree); extern bool reduced_constant_expression_p (tree); extern bool is_instantiation_of_constexpr (tree); Index: pt.c =================================================================== --- pt.c (revision 217468) +++ pt.c (working copy) @@ -15138,8 +15138,7 @@ tsubst_copy_and_build (tree t, case COND_EXPR: { tree cond = RECUR (TREE_OPERAND (t, 0)); - tree folded_cond = (maybe_constant_value - (fold_non_dependent_expr_sfinae (cond, tf_none))); + tree folded_cond = maybe_constant_folded_value (cond); tree exp1, exp2; if (TREE_CODE (folded_cond) == INTEGER_CST) @@ -21864,7 +21863,7 @@ build_non_dependent_expr (tree expr) /* Try to get a constant value for all non-dependent expressions in order to expose bugs in *_dependent_expression_p and constexpr. */ if (cxx_dialect >= cxx11) - maybe_constant_value (fold_non_dependent_expr_sfinae (expr, tf_none)); + maybe_constant_folded_value (expr); #endif /* Preserve OVERLOADs; the functions must be available to resolve Index: semantics.c =================================================================== --- semantics.c (revision 217468) +++ semantics.c (working copy) @@ -511,8 +511,7 @@ begin_maybe_infinite_loop (tree cond) bool maybe_infinite = true; if (cond) { - cond = fold_non_dependent_expr_sfinae (cond, tf_none); - cond = maybe_constant_value (cond); + cond = maybe_constant_folded_value (cond); maybe_infinite = integer_nonzerop (cond); } vec_safe_push (cp_function_chain->infinite_loops, Index: typeck.c =================================================================== --- typeck.c (revision 217468) +++ typeck.c (working copy) @@ -4133,8 +4133,7 @@ cp_build_binary_op (location_t location, || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)) { enum tree_code tcode0 = code0, tcode1 = code1; - tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none); - cop1 = maybe_constant_value (cop1); + tree cop1 = maybe_constant_folded_value (op1); doing_div_or_mod = true; warn_for_div_by_zero (location, cop1); @@ -4173,8 +4172,7 @@ cp_build_binary_op (location_t location, case TRUNC_MOD_EXPR: case FLOOR_MOD_EXPR: { - tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none); - cop1 = maybe_constant_value (cop1); + tree cop1 = maybe_constant_folded_value (op1); doing_div_or_mod = true; warn_for_div_by_zero (location, cop1); } @@ -4268,8 +4266,7 @@ cp_build_binary_op (location_t location, } else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { - tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none); - const_op1 = maybe_constant_value (const_op1); + tree const_op1 = maybe_constant_folded_value (op1); if (TREE_CODE (const_op1) != INTEGER_CST) const_op1 = op1; result_type = type0; @@ -4318,8 +4315,7 @@ cp_build_binary_op (location_t location, } else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { - tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none); - const_op1 = maybe_constant_value (const_op1); + tree const_op1 = maybe_constant_folded_value (op1); if (TREE_CODE (const_op1) != INTEGER_CST) const_op1 = op1; result_type = type0; @@ -4991,10 +4987,8 @@ cp_build_binary_op (location_t location, /* OP0 and/or OP1 might have side-effects. */ op0 = cp_save_expr (op0); op1 = cp_save_expr (op1); - op0 = maybe_constant_value (fold_non_dependent_expr_sfinae (op0, - tf_none)); - op1 = maybe_constant_value (fold_non_dependent_expr_sfinae (op1, - tf_none)); + op0 = maybe_constant_folded_value (op0); + op1 = maybe_constant_folded_value (op1); if (doing_div_or_mod && (flag_sanitize & (SANITIZE_DIVIDE | SANITIZE_FLOAT_DIVIDE))) { Index: typeck2.c =================================================================== --- typeck2.c (revision 217468) +++ typeck2.c (working copy) @@ -872,7 +872,7 @@ check_narrowing (tree type, tree init, tsubst_flag return ok; } - init = maybe_constant_value (fold_non_dependent_expr_sfinae (init, tf_none)); + init = maybe_constant_folded_value (init); if (TREE_CODE (type) == INTEGER_TYPE && TREE_CODE (ftype) == REAL_TYPE)