public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Patrick Palka <ppalka@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-6119] c++: make manifestly_const_eval tri-state Date: Fri, 17 Feb 2023 20:21:32 +0000 (GMT) [thread overview] Message-ID: <20230217202132.4B901385828E@sourceware.org> (raw) https://gcc.gnu.org/g:3a0bc47cdb670c8f1e0996e6255ee1084eb7febf commit r13-6119-g3a0bc47cdb670c8f1e0996e6255ee1084eb7febf Author: Patrick Palka <ppalka@redhat.com> Date: Fri Feb 17 15:18:08 2023 -0500 c++: make manifestly_const_eval tri-state This patch converts the constexpr machinery's manifestly_const_eval flag into a tri-state enum to allow us to express wanting to fold __builtin_is_constant_evaluated to false via speculative constexpr evaluation. For now, only the maybe_constant_value entry point is changed to take this enum; the others continue to take bool. The subsequent patch will teach cp_fold (which uses maybe_constant_value) to fold the builtin to false when called from cp_fold_function and cp_fully_fold_init. gcc/cp/ChangeLog: * constexpr.cc (constexpr_call::manifestly_const_eval): Give it type int instead of bool. (constexpr_ctx::manifestly_const_eval): Give it type mce_value instead of bool. (cxx_eval_builtin_function_call): Adjust after making manifestly_const_eval tri-state. (cxx_eval_call_expression): Likewise. (cxx_eval_binary_expression): Likewise. (cxx_eval_conditional_expression): Likewise. (cxx_eval_constant_expression): Likewise. (cxx_eval_outermost_constant_expr): Likewise. (cxx_constant_value): Likewise. (cxx_constant_dtor): Likewise. (maybe_constant_value): Give manifestly_const_eval parameter type mce_value instead of bool and adjust accordingly. (fold_non_dependent_expr_template): Adjust call to cxx_eval_outermost_constant_expr. (fold_non_dependent_expr): Likewise. (maybe_constant_init_1): Likewise. * constraint.cc (satisfy_atom): Adjust call to maybe_constant_value. * cp-tree.h (enum class mce_value): Define. (maybe_constant_value): Adjust manifestly_const_eval parameter type and default argument. * decl.cc (compute_array_index_type_loc): Adjust call to maybe_constant_value. * pt.cc (convert_nontype_argument): Likewise. Diff: --- gcc/cp/constexpr.cc | 59 ++++++++++++++++++++++++++++------------------------ gcc/cp/constraint.cc | 3 +-- gcc/cp/cp-tree.h | 20 +++++++++++++++++- gcc/cp/decl.cc | 2 +- gcc/cp/pt.cc | 6 ++---- 5 files changed, 55 insertions(+), 35 deletions(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 564766c8a00..aa2c14355f8 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -1119,8 +1119,8 @@ struct GTY((for_user)) constexpr_call { /* The hash of this call; we remember it here to avoid having to recalculate it when expanding the hash table. */ hashval_t hash; - /* Whether __builtin_is_constant_evaluated() should evaluate to true. */ - bool manifestly_const_eval; + /* The value of constexpr_ctx::manifestly_const_eval. */ + enum mce_value manifestly_const_eval; }; struct constexpr_call_hasher : ggc_ptr_hash<constexpr_call> @@ -1248,7 +1248,7 @@ struct constexpr_ctx { trying harder to get a constant value. */ bool strict; /* Whether __builtin_is_constant_evaluated () should be true. */ - bool manifestly_const_eval; + mce_value manifestly_const_eval; }; /* This internal flag controls whether we should avoid doing anything during @@ -1463,7 +1463,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, /* If we aren't requiring a constant expression, defer __builtin_constant_p in a constexpr function until we have values for the parameters. */ if (bi_const_p - && !ctx->manifestly_const_eval + && ctx->manifestly_const_eval != mce_true && current_function_decl && DECL_DECLARED_CONSTEXPR_P (current_function_decl)) { @@ -1479,12 +1479,13 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED, BUILT_IN_FRONTEND)) { - if (!ctx->manifestly_const_eval) + if (ctx->manifestly_const_eval == mce_unknown) { *non_constant_p = true; return t; } - return boolean_true_node; + return constant_boolean_node (ctx->manifestly_const_eval == mce_true, + boolean_type_node); } if (fndecl_built_in_p (fun, CP_BUILT_IN_SOURCE_LOCATION, BUILT_IN_FRONTEND)) @@ -1591,7 +1592,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, } bool save_ffbcp = force_folding_builtin_constant_p; - force_folding_builtin_constant_p |= ctx->manifestly_const_eval; + force_folding_builtin_constant_p |= ctx->manifestly_const_eval == mce_true; tree save_cur_fn = current_function_decl; /* Return name of ctx->call->fundef->decl for __builtin_FUNCTION (). */ if (fndecl_built_in_p (fun, BUILT_IN_FUNCTION) @@ -2916,7 +2917,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, location_t save_loc = input_location; input_location = loc; ++function_depth; - if (ctx->manifestly_const_eval) + if (ctx->manifestly_const_eval == mce_true) FNDECL_MANIFESTLY_CONST_EVALUATED (fun) = true; instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false); --function_depth; @@ -3676,7 +3677,7 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t, if (r == NULL_TREE) { - if (ctx->manifestly_const_eval + if (ctx->manifestly_const_eval == mce_true && (flag_constexpr_fp_except || TREE_CODE (type) != REAL_TYPE)) { @@ -3741,13 +3742,13 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t, without manifestly_const_eval even expressions or parts thereof which will later be manifestly const_eval evaluated), otherwise fold it to true. */ - if (ctx->manifestly_const_eval) - val = boolean_true_node; - else + if (ctx->manifestly_const_eval == mce_unknown) { *non_constant_p = true; return t; } + val = constant_boolean_node (ctx->manifestly_const_eval == mce_true, + boolean_type_node); } /* Don't VERIFY_CONSTANT the other operands. */ if (integer_zerop (val)) @@ -7051,7 +7052,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, r = v; break; } - if (ctx->manifestly_const_eval) + if (ctx->manifestly_const_eval == mce_true) maybe_warn_about_constant_value (loc, t); if (COMPLETE_TYPE_P (TREE_TYPE (t)) && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false)) @@ -7640,7 +7641,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, if (TREE_CODE (t) == CONVERT_EXPR && ARITHMETIC_TYPE_P (type) && INDIRECT_TYPE_P (TREE_TYPE (op)) - && ctx->manifestly_const_eval) + && ctx->manifestly_const_eval == mce_true) { if (!ctx->quiet) error_at (loc, @@ -8178,7 +8179,7 @@ mark_non_constant (tree t) static tree cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, bool strict = true, - bool manifestly_const_eval = false, + mce_value manifestly_const_eval = mce_unknown, bool constexpr_dtor = false, tree object = NULL_TREE) { @@ -8196,10 +8197,11 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, constexpr_global_ctx global_ctx; constexpr_ctx ctx = { &global_ctx, NULL, NULL, NULL, NULL, NULL, NULL, allow_non_constant, strict, - manifestly_const_eval || !allow_non_constant }; + !allow_non_constant ? mce_true : manifestly_const_eval }; /* Turn off -frounding-math for manifestly constant evaluation. */ - warning_sentinel rm (flag_rounding_math, ctx.manifestly_const_eval); + warning_sentinel rm (flag_rounding_math, + ctx.manifestly_const_eval == mce_true); tree type = initialized_type (t); tree r = t; bool is_consteval = false; @@ -8288,7 +8290,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, auto_vec<tree, 16> cleanups; global_ctx.cleanups = &cleanups; - if (manifestly_const_eval) + if (manifestly_const_eval == mce_true) instantiate_constexpr_fns (r); r = cxx_eval_constant_expression (&ctx, r, vc_prvalue, &non_constant_p, &overflow_p); @@ -8427,7 +8429,7 @@ cxx_constant_value (tree t, tree decl /* = NULL_TREE */, tsubst_flags_t complain /* = tf_error */) { bool sfinae = !(complain & tf_error); - tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, true, false, decl); + tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, mce_true, false, decl); if (sfinae && !TREE_CONSTANT (r)) r = error_mark_node; return r; @@ -8439,7 +8441,7 @@ cxx_constant_value (tree t, tree decl /* = NULL_TREE */, void cxx_constant_dtor (tree t, tree decl) { - cxx_eval_outermost_constant_expr (t, false, true, true, true, decl); + cxx_eval_outermost_constant_expr (t, false, true, mce_true, true, decl); } /* Helper routine for fold_simple function. Either return simplified @@ -8525,7 +8527,7 @@ static GTY((deletable)) hash_map<tree, tree> *cv_cache; tree maybe_constant_value (tree t, tree decl /* = NULL_TREE */, - bool manifestly_const_eval /* = false */) + mce_value manifestly_const_eval /* = mce_unknown */) { tree r; @@ -8540,8 +8542,9 @@ maybe_constant_value (tree t, tree decl /* = NULL_TREE */, /* No caching or evaluation needed. */ return t; - if (manifestly_const_eval) - return cxx_eval_outermost_constant_expr (t, true, true, true, false, decl); + if (manifestly_const_eval != mce_unknown) + return cxx_eval_outermost_constant_expr (t, true, true, + manifestly_const_eval, false, decl); if (cv_cache == NULL) cv_cache = hash_map<tree, tree>::create_ggc (101); @@ -8565,7 +8568,8 @@ maybe_constant_value (tree t, tree decl /* = NULL_TREE */, return t; uid_sensitive_constexpr_evaluation_checker c; - r = cxx_eval_outermost_constant_expr (t, true, true, false, false, decl); + r = cxx_eval_outermost_constant_expr (t, true, true, + manifestly_const_eval, false, decl); gcc_checking_assert (r == t || CONVERT_EXPR_P (t) || TREE_CODE (t) == VIEW_CONVERT_EXPR @@ -8631,7 +8635,7 @@ fold_non_dependent_expr_template (tree t, tsubst_flags_t complain, return t; tree r = cxx_eval_outermost_constant_expr (t, true, true, - manifestly_const_eval, + mce_value (manifestly_const_eval), false, object); /* cp_tree_equal looks through NOPs, so allow them. */ gcc_checking_assert (r == t @@ -8678,7 +8682,7 @@ fold_non_dependent_expr (tree t, return fold_non_dependent_expr_template (t, complain, manifestly_const_eval, object); - return maybe_constant_value (t, object, manifestly_const_eval); + return maybe_constant_value (t, object, mce_value (manifestly_const_eval)); } /* Like fold_non_dependent_expr, but if EXPR couldn't be folded to a constant, @@ -8756,7 +8760,8 @@ maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant, bool is_static = (decl && DECL_P (decl) && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))); t = cxx_eval_outermost_constant_expr (t, allow_non_constant, !is_static, - manifestly_const_eval, false, decl); + mce_value (manifestly_const_eval), + false, decl); } if (TREE_CODE (t) == TARGET_EXPR) { diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 2e5acdf8fcb..9374327008b 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3068,8 +3068,7 @@ satisfy_atom (tree t, tree args, sat_info info) } else { - result = maybe_constant_value (result, NULL_TREE, - /*manifestly_const_eval=*/true); + result = maybe_constant_value (result, NULL_TREE, mce_true); if (!TREE_CONSTANT (result)) result = error_mark_node; } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4ecd9c7f21f..5595335bbf7 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8459,6 +8459,24 @@ struct GTY((for_user)) constexpr_fundef { tree result; }; +/* Whether the current context is manifestly constant-evaluated. + Used by the constexpr machinery to control folding of + __builtin_is_constant_evaluated. */ + +enum class mce_value +{ + /* Unknown, so treat __builtin_is_constant_evaluated as non-constant. */ + mce_unknown = 0, + /* Fold it to true. */ + mce_true = 1, + /* Fold it to false. Primarily used during cp_fold_function and + cp_fully_fold_init. */ + mce_false = -1, +}; +constexpr mce_value mce_unknown = mce_value::mce_unknown; +constexpr mce_value mce_true = mce_value::mce_true; +constexpr mce_value mce_false = mce_value::mce_false; + extern void fini_constexpr (void); extern bool literal_type_p (tree); extern void maybe_save_constexpr_fundef (tree); @@ -8487,7 +8505,7 @@ inline tree cxx_constant_value (tree t, tsubst_flags_t complain) { return cxx_constant_value (t, NULL_TREE, complain); } extern void cxx_constant_dtor (tree, tree); extern tree cxx_constant_init (tree, tree = NULL_TREE); -extern tree maybe_constant_value (tree, tree = NULL_TREE, bool = false); +extern tree maybe_constant_value (tree, tree = NULL_TREE, mce_value = mce_unknown); extern tree maybe_constant_init (tree, tree = NULL_TREE, bool = false); extern tree fold_non_dependent_expr (tree, tsubst_flags_t = tf_warning_or_error, diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 2f6412d04e6..30c7470974d 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -11373,7 +11373,7 @@ compute_array_index_type_loc (location_t name_loc, tree name, tree size, cp_convert (ssizetype, integer_one_node, complain), complain); - itype = maybe_constant_value (itype, NULL_TREE, true); + itype = maybe_constant_value (itype, NULL_TREE, mce_true); } if (!TREE_CONSTANT (itype)) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index d11d540ab44..b1ac7d4beb4 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -7390,16 +7390,14 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) IMPLICIT_CONV_EXPR_NONTYPE_ARG (expr) = true; return expr; } - expr = maybe_constant_value (expr, NULL_TREE, - /*manifestly_const_eval=*/true); + expr = maybe_constant_value (expr, NULL_TREE, mce_true); expr = convert_from_reference (expr); /* EXPR may have become value-dependent. */ val_dep_p = value_dependent_expression_p (expr); } else if (TYPE_PTR_OR_PTRMEM_P (type)) { - tree folded = maybe_constant_value (expr, NULL_TREE, - /*manifestly_const_eval=*/true); + tree folded = maybe_constant_value (expr, NULL_TREE, mce_true); if (TYPE_PTR_P (type) ? integer_zerop (folded) : null_member_pointer_value_p (folded)) expr = folded;
reply other threads:[~2023-02-17 20:21 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230217202132.4B901385828E@sourceware.org \ --to=ppalka@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).