From 234bef96a1cff5d8ad577777fae051105ec01b6e Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Fri, 14 Nov 2014 16:59:52 +0000 Subject: [PATCH] semantics.c (end_maybe_infinite_loop): Use fold_non_dependent_expr. 2014-11-14 Paolo Carlini * 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 --- gcc/cp/ChangeLog | 38 ++++++++++++++++++++++++ gcc/cp/call.c | 8 ++--- gcc/cp/class.c | 9 +++--- gcc/cp/constexpr.c | 73 +++++++++++++++++++++++++++++++++++++++++++++- gcc/cp/cp-tree.h | 5 ++-- gcc/cp/decl.c | 7 ++++- gcc/cp/decl2.c | 2 +- gcc/cp/parser.c | 6 +--- gcc/cp/pt.c | 17 +++++------ gcc/cp/semantics.c | 6 ++-- gcc/cp/tree.c | 2 +- gcc/cp/typeck.c | 20 +++++-------- gcc/cp/typeck2.c | 6 ++-- 13 files changed, 151 insertions(+), 48 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ddef4ff68b2..5311649d12d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,41 @@ +2014-11-14 Paolo Carlini + + * 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 * mangle.c (find_substitution): Look for abi_tag on class templates. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index bf191cadfd4..4f0b1725da2 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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 = fold_non_dependent_expr (t); STRIP_NOPS (t); if (integer_zerop (t) && !TREE_OVERFLOW (t)) return true; @@ -7437,8 +7437,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) return error_mark_node; if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0 - /* Don't mess with virtual lookup in fold_non_dependent_expr; virtual - functions can't be constexpr. */ + /* Don't mess with virtual lookup in instantiate_non_dependent_expr; + virtual functions can't be constexpr. */ && !in_template_function ()) { 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 perform the actual conversion. But for initializers, we 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); if (!(flags & LOOKUP_ONLYCONVERTING)) IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true; diff --git a/gcc/cp/class.c b/gcc/cp/class.c index ce1d07c90ef..c83c8adfab2 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -359,9 +359,9 @@ build_base_path (enum tree_code code, /* 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 - template (even in fold_non_dependent_expr), we don't have vtables set - up properly yet, and the value doesn't matter there either; we're just - interested in the result of overload resolution. */ + template (even in instantiate_non_dependent_expr), we don't have vtables + set up properly yet, and the value doesn't matter there either; we're + just interested in the result of overload resolution. */ if (cp_unevaluated_operand != 0 || in_template_function ()) { @@ -6933,7 +6933,8 @@ resolves_to_fixed_type_p (tree instance, int* nonnull) tree fixed; /* 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 ()) { /* In a template we only care about the type of the result. */ diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 3901e9a53da..d30bf635d84 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2908,12 +2908,83 @@ maybe_constant_value (tree t, tree decl) /* 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; } +/* 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 void f(T[1 + 1]); + template 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 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)) return false; /* 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) denom = cxx_eval_outermost_constant_expr (denom, true); if (integer_zerop (denom)) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7a1a0f74b02..b69c7369589 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5690,8 +5690,8 @@ extern tree template_for_substitution (tree); extern tree build_non_dependent_expr (tree); extern void make_args_non_dependent (vec *); extern bool reregister_specialization (tree, tree, tree); -extern tree fold_non_dependent_expr (tree); -extern tree fold_non_dependent_expr_sfinae (tree, tsubst_flags_t); +extern tree instantiate_non_dependent_expr (tree); +extern tree instantiate_non_dependent_expr_sfinae (tree, tsubst_flags_t); extern bool alias_type_or_template_p (tree); extern bool alias_template_specialization_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 maybe_constant_value (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 reduced_constant_expression_p (tree); extern bool is_instantiation_of_constexpr (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9ca32e37d95..1ef97637426 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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. */; else { - size = fold_non_dependent_expr_sfinae (size, complain); + size = instantiate_non_dependent_expr_sfinae (size, complain); if (CLASS_TYPE_P (type) && CLASSTYPE_LITERAL_P (type)) @@ -12999,6 +12999,11 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc) tree context; 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 result in the enum being assigned the next value in sequence. */ if (value == error_mark_node) diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index ff407101f08..1b686ef95ae 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4951,7 +4951,7 @@ mark_used (tree decl, tsubst_flags_t complain) if (processing_template_decl) 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) && uses_template_parms (DECL_TI_ARGS (decl))) return true; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 93520bc4ecf..3ab65a91556 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -6886,7 +6886,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, } 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 expansion. */ @@ -15996,10 +15996,6 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type) if (check_for_bare_parameter_packs (value)) 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. */ build_enumerator (identifier, value, type, loc); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f408680abbf..1ee3dc11906 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5216,7 +5216,7 @@ redeclare_class_template (tree type, tree parms) (possibly simplified) expression. */ 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) return NULL_TREE; @@ -5248,9 +5248,9 @@ fold_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain) } 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 @@ -5740,7 +5740,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) && has_value_dependent_address (expr)) /* If we want the address and it's value-dependent, don't fold. */; 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)) return error_mark_node; expr_type = TREE_TYPE (expr); @@ -8314,7 +8314,7 @@ uses_template_parms (tree t) /* Returns true iff current_function_decl is an incompletely instantiated 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 in_template_function (void) @@ -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 = fold_non_dependent_expr (cond); tree exp1, exp2; if (TREE_CODE (folded_cond) == INTEGER_CST) @@ -21110,7 +21109,7 @@ value_dependent_expression_p (tree expression) case STMT_EXPR: /* 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; default: @@ -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)); + fold_non_dependent_expr (expr); #endif /* Preserve OVERLOADs; the functions must be available to resolve diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index ebd9a43b949..6888121d5d0 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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 = fold_non_dependent_expr (cond); maybe_infinite = integer_nonzerop (cond); } vec_safe_push (cp_function_chain->infinite_loops, @@ -543,7 +542,6 @@ end_maybe_infinite_loop (tree cond) if (current != NULL_TREE) { cond = fold_non_dependent_expr (cond); - cond = maybe_constant_value (cond); if (integer_nonzerop (cond)) 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. */ - condition = fold_non_dependent_expr (condition); + condition = instantiate_non_dependent_expr (condition); condition = cp_convert (boolean_type_node, condition, tf_warning_or_error); condition = maybe_constant_value (condition); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index e0c2af1576c..21cecc2e39c 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -4143,7 +4143,7 @@ fold_if_not_in_template (tree expr) /* In the body of a template, there is never any need to call "fold". We will call fold later when actually instantiating the 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) return expr; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 184363e6446..05bc916cdc7 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1787,7 +1787,7 @@ cxx_alignas_expr (tree e) /* Leave value-dependent expression alone for now. */ return e; - e = fold_non_dependent_expr (e); + e = instantiate_non_dependent_expr (e); e = mark_rvalue_use (e); /* [dcl.align]/2 says: @@ -4135,8 +4135,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 = fold_non_dependent_expr (op1); doing_div_or_mod = true; warn_for_div_by_zero (location, cop1); @@ -4175,8 +4174,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 = fold_non_dependent_expr (op1); doing_div_or_mod = true; 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) { - tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none); - const_op1 = maybe_constant_value (const_op1); + tree const_op1 = fold_non_dependent_expr (op1); if (TREE_CODE (const_op1) != INTEGER_CST) const_op1 = op1; result_type = type0; @@ -4320,8 +4317,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 = fold_non_dependent_expr (op1); if (TREE_CODE (const_op1) != INTEGER_CST) const_op1 = op1; result_type = type0; @@ -4993,10 +4989,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 = fold_non_dependent_expr (op0); + op1 = fold_non_dependent_expr (op1); if (doing_div_or_mod && (flag_sanitize & (SANITIZE_DIVIDE | SANITIZE_FLOAT_DIVIDE))) { diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index d57f75dadc5..01a0671341e 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -797,7 +797,7 @@ store_init_value (tree decl, tree init, vec** cleanups, int flags) if (decl_maybe_constant_var_p (decl) || TREE_STATIC (decl)) { bool const_init; - value = fold_non_dependent_expr (value); + value = instantiate_non_dependent_expr (value); if (DECL_DECLARED_CONSTEXPR_P (decl) || DECL_IN_AGGR_P (decl)) { @@ -872,7 +872,7 @@ check_narrowing (tree type, tree init, tsubst_flags_t complain) 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 && 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); /* When we defer constant folding within a statement, we may want to 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); if (TREE_CONSTANT (t)) init = t; -- 2.30.2