From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 70B383858D1E for ; Mon, 30 Jan 2023 20:02:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 70B383858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1675108952; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=C2St9IqQHGMJ1ui+dMA6gb/Bq4i07C5yS8W7AZZnWWM=; b=IAo0gzTHuBUAOhXjywieLjoXlmWAMY9wzcG0r801r8SHXnwWuJHEtmAA9kBrWSMdWYhyJ4 XYaXNAHI+LIa1zgavJGmYJHR96G9XQ3JA1NTqxb0c43MxFDhhuj7R8l6DHtL3FNlDb9/uU Ml+DygixBSqhlIkcjJpB8INvoHTTVkI= Received: from mail-yw1-f200.google.com (mail-yw1-f200.google.com [209.85.128.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-599-u6vofflkMAChQqLGqjrY0A-1; Mon, 30 Jan 2023 15:02:21 -0500 X-MC-Unique: u6vofflkMAChQqLGqjrY0A-1 Received: by mail-yw1-f200.google.com with SMTP id 00721157ae682-517f8be4b00so27232907b3.3 for ; Mon, 30 Jan 2023 12:02:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:in-reply-to:from:references:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=C2St9IqQHGMJ1ui+dMA6gb/Bq4i07C5yS8W7AZZnWWM=; b=ZYWQYzW9x+0wCoGM6JU+fLkhofak8/5QWX3Xdq7mWCPOXBSmqw2JTDPNu13fJikWw0 pQbRIwI0ZGqozEDvFeFsxK5LZ7wf/7X6JwUnPHPRmnnJkoMxbAVC2RXGwpZ5m2h7SvRD mGnmq5Y2vQ1l7B9KyFmUBPPZ4s2pZUXVcq08iwu2b0hqlmaHGL8LI8VnH+K2Kvr28lun OIbaByYBKiVEexm/QnFSLsaFfWbiWOvsmKOVvQShhMRwTYq7UHKqI/wwGLfi0qkbX/aI Tpu3wUek/wV+w1u863Rajj7Ja+Zw5kziM/r1dKNrToBLdo135eaPUjF9f4zL82MjYahk dWNw== X-Gm-Message-State: AO0yUKUwlNY9YHyhlU0WFoVGX+6DuN8QtDUMjuaJ2cMfpW1tPY0OhHFD YdDmT82zlQ3iZPqtWQl/m0W5n9vPBKYONDu6wClrtsn53MeVm4T43byOgYNMdNmKn6II4MrfDup fp7OIeoglZ9viJW9/yg== X-Received: by 2002:a05:6902:691:b0:7b5:bc5c:938f with SMTP id i17-20020a056902069100b007b5bc5c938fmr7400534ybt.53.1675108940314; Mon, 30 Jan 2023 12:02:20 -0800 (PST) X-Google-Smtp-Source: AK7set/mxE+o3JEL2SQJWSpoHvjebH7GrkAzaodQBlrFkn5tiDKvaSkNp8Fp5D16oGRYOQwSreUW6A== X-Received: by 2002:a05:6902:691:b0:7b5:bc5c:938f with SMTP id i17-20020a056902069100b007b5bc5c938fmr7400504ybt.53.1675108939848; Mon, 30 Jan 2023 12:02:19 -0800 (PST) Received: from [192.168.1.108] (130-44-159-43.s15913.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.159.43]) by smtp.gmail.com with ESMTPSA id q187-20020a378ec4000000b006f7ee901674sm4773407qkd.2.2023.01.30.12.02.18 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 30 Jan 2023 12:02:19 -0800 (PST) Message-ID: <2561e459-73a1-c79e-0dbb-9fbe87da81de@redhat.com> Date: Mon, 30 Jan 2023 15:02:18 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.6.1 Subject: Re: [PATCH 1/2] c++: make manifestly_const_eval tri-state To: Patrick Palka , gcc-patches@gcc.gnu.org References: <20230127220250.1896137-1-ppalka@redhat.com> From: Jason Merrill In-Reply-To: <20230127220250.1896137-1-ppalka@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 1/27/23 17:02, Patrick Palka wrote: > This patch turns the manifestly_const_eval flag used by the constexpr > machinery into a tri-state enum so that we're able to express wanting > to fold __builtin_is_constant_evaluated to false via late speculative > constexpr evaluation. Of all the entry points to constexpr evaluation > only maybe_constant_value is changed to take a tri-state value; the > others continue to take bool. The subsequent patch will use this to fold > the builtin to false when called from cp_fold_function. > > 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. > --- > gcc/cp/constexpr.cc | 61 ++++++++++++++++++++++++-------------------- > gcc/cp/constraint.cc | 3 +-- > gcc/cp/cp-tree.h | 18 ++++++++++++- > gcc/cp/decl.cc | 2 +- `> gcc/cp/pt.cc | 6 ++--- > 5 files changed, 54 insertions(+), 36 deletions(-) > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > index be99bec17e7..34662198903 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 raw value of constexpr_ctx::manifestly_const_eval. */ > + int manifestly_const_eval; Why not mce_value? > }; > > struct constexpr_call_hasher : ggc_ptr_hash > @@ -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_unknown > && 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_unknown; > 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) > @@ -2644,7 +2645,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, > location_t loc = cp_expr_loc_or_input_loc (t); > tree fun = get_function_named_in_call (t); > constexpr_call new_call > - = { NULL, NULL, NULL, 0, ctx->manifestly_const_eval }; > + = { NULL, NULL, NULL, 0, (int)ctx->manifestly_const_eval }; > int depth_ok; > > if (fun == NULL_TREE) > @@ -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)) > @@ -7055,7 +7056,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)) > @@ -7644,7 +7645,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, > @@ -8137,7 +8138,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) > { > @@ -8155,10 +8156,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; > @@ -8247,7 +8249,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, > auto_vec 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); > @@ -8386,7 +8388,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; > @@ -8398,7 +8400,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 > @@ -8484,7 +8486,7 @@ static GTY((deletable)) hash_map *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; > > @@ -8499,8 +8501,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::create_ggc (101); > @@ -8524,7 +8527,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 > @@ -8590,7 +8594,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 > @@ -8637,7 +8641,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, > @@ -8715,7 +8719,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 74b7ab71ca5..2d39185b182 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -8456,6 +8456,22 @@ struct GTY((for_user)) constexpr_fundef { > tree result; > }; > > +/* Used by the constexpr machinery to control folding of > + __builtin_is_constant_evaluated. */ Add "Whether the current context is manifestly constant-evaluated." at the start. > +enum class mce_value > +{ > + /* Treat __builtin_is_constant_evaluated as non-constant. */ "Unknown, so..." > + mce_unknown = 0, > + /* Fold it to true. */ > + mce_true = 1, > + /* Fold it to false. */ "Primarily used during cp_fold_function." OK with these tweaks. > + 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); > @@ -8484,7 +8500,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 d606b31d7a7..a023c38c59d 100644 > --- a/gcc/cp/decl.cc > +++ b/gcc/cp/decl.cc > @@ -11372,7 +11372,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 64e9128a5f1..4d82666891c 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;