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.133.124]) by sourceware.org (Postfix) with ESMTPS id 740A63858000 for ; Fri, 3 Feb 2023 21:22:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 740A63858000 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=1675459324; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=72kvwJkstKPUyhhTx4p8X2sGbf1pF9KYUZyiJQX13Ro=; b=Hp5/W9faiXPWwAsXgyuOtuRRlmHQTm1hs0osedKx6lHM8zNQed1S3ZFzcb0H+o00sjZkOF Wb41nJ3PxLvxTMTnUItYjXWbz5O11re1pf8d28sJanu0GhgclCNCgqp3Wvk+S55G7Z+2CG WHbe0/e10oE1LSWVopQJc9Mn8MaIylc= Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-132-F_nUQHaANr-W3GZyPh1G_w-1; Fri, 03 Feb 2023 16:22:02 -0500 X-MC-Unique: F_nUQHaANr-W3GZyPh1G_w-1 Received: by mail-qt1-f197.google.com with SMTP id j26-20020ac84c9a000000b003b9b7c60108so3291134qtv.16 for ; Fri, 03 Feb 2023 13:22:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=mime-version:references:message-id:in-reply-to:subject:cc:to:date :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=72kvwJkstKPUyhhTx4p8X2sGbf1pF9KYUZyiJQX13Ro=; b=dKoATaYH3w+7eRb3W7Pbt33RyfaFwB6I/NmDN+GDNjTUKHlQF3RB0fgQSu0AyytSi4 VwI9nChnDk3rnPomT2HTjSOhWvkEF5DGf+Da700zR+kM3ngeBWoQ1WXFpkpF9jfRvjdg nts1GwdWLs8yPoODN1OiYik8AB8qzZLgymG4Cuw5m6XgUYrLKhD9AXjEDdVevKpOKkdv +q8pDVTUWcVBCbUwKvzKNY3Ow304rGKDT4dIQdNxbSeDyYgguReQKnZhVbWbmC6fbLwR D+Y57Eer8p7MuVWE3DfZI4QjA5tPGBgPpYb4vynyaLiPTTN3xQrrw16g5WqpxdLwyYK5 e5tg== X-Gm-Message-State: AO0yUKWCoFLQRc0V5KlWuSxWIVspbvSMfD2dn9ww91KAuI4ZUJeBkZSX 5wf1L7aZcLtvcJej0KfygUZ53OBQ6BiEu0rIXWe2Xc5CbYuv+5aCChm0v4wE+vF9okD11NZWQeB N1GzBmPXXZ/p0nDiifQ== X-Received: by 2002:ac8:4e52:0:b0:3b8:6b0c:9fd with SMTP id e18-20020ac84e52000000b003b86b0c09fdmr20103343qtw.44.1675459321425; Fri, 03 Feb 2023 13:22:01 -0800 (PST) X-Google-Smtp-Source: AK7set8LJ8UyeifS2nUyTovqIGDSc+0jU3dPGsNACGNjURog73oQ3gsvrnpBO8vpbCIULRenHuGc6w== X-Received: by 2002:ac8:4e52:0:b0:3b8:6b0c:9fd with SMTP id e18-20020ac84e52000000b003b86b0c09fdmr20103294qtw.44.1675459320949; Fri, 03 Feb 2023 13:22:00 -0800 (PST) Received: from [192.168.1.130] (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id d23-20020ac800d7000000b003b8238114d9sm2275671qtg.12.2023.02.03.13.22.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Feb 2023 13:22:00 -0800 (PST) From: Patrick Palka X-Google-Original-From: Patrick Palka Date: Fri, 3 Feb 2023 16:21:59 -0500 (EST) To: Jason Merrill cc: Patrick Palka , gcc-patches@gcc.gnu.org Subject: Re: [PATCH 1/2] c++: make manifestly_const_eval tri-state In-Reply-To: <2561e459-73a1-c79e-0dbb-9fbe87da81de@redhat.com> Message-ID: <208dc259-aa47-fc57-b569-1c99db7e81f2@idea> References: <20230127220250.1896137-1-ppalka@redhat.com> <2561e459-73a1-c79e-0dbb-9fbe87da81de@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-13.9 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,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 Mon, 30 Jan 2023, Jason Merrill wrote: > 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? gengtype complained about 'mce_value' being an unknown type here (constexpr_call is gengtype-enabled). Ah, but it looks like using 'enum mce_value' makes gengtype happy. > > > }; > > 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. Thanks, here's v2 with the above changes, pending approval of the second patch of the series. I'll make sure to adjust the comment for mce_value::mce_false to say "Primarily used during cp_fold_function and cp_fully_fold_init" if we do end up using it from cp_fully_fold_init as well. -- >8 -- Subject: [PATCH 1/2] c++: make manifestly_const_eval tri-state 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 | 59 ++++++++++++++++++++++++-------------------- gcc/cp/constraint.cc | 3 +-- gcc/cp/cp-tree.h | 19 +++++++++++++- gcc/cp/decl.cc | 2 +- gcc/cp/pt.cc | 6 ++--- 5 files changed, 54 insertions(+), 35 deletions(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 5b31f9c27d1..4576aebd8d2 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 @@ -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) @@ -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, @@ -8182,7 +8183,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) { @@ -8200,10 +8201,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; @@ -8292,7 +8294,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); @@ -8431,7 +8433,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; @@ -8443,7 +8445,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 @@ -8529,7 +8531,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; @@ -8544,8 +8546,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); @@ -8569,7 +8572,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 @@ -8635,7 +8639,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 @@ -8682,7 +8686,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, @@ -8760,7 +8764,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 31fd8af4f21..00b2bffc85c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8455,6 +8455,23 @@ 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. */ + 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); @@ -8483,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 51fc246ed71..255332dc0c1 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; -- 2.39.1.388.g2fc9e9ca3c