From patchwork Fri Jan 27 22:02:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 49703 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp1065176wrn; Fri, 27 Jan 2023 14:04:13 -0800 (PST) X-Google-Smtp-Source: AK7set9NVUoRxf855CyXCdfDqyDuXgROPx0q64S9eh7Dq0bWHBmEqluECUt2DxdfVG5RQrW39qet X-Received: by 2002:a05:6402:40cd:b0:4a0:d0b6:f458 with SMTP id z13-20020a05640240cd00b004a0d0b6f458mr10648310edb.16.1674857053754; Fri, 27 Jan 2023 14:04:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1674857053; cv=none; d=google.com; s=arc-20160816; b=mc0TBlWCNFqmMVfhx6W4TyDsAIgSN/5xdVwEvWiSuWGryFC+165Ee5FHOtEl/ZJMop 3K4Tj3IBqXoqKvT6/hhCzpvtmb9+LMCrEImVFYH8ANq2EOZLhnRBNb/AUAJ374yjVsXo l2idpid9b14Mgcxr2nb9iipIiquU9Cy4YY/p/uwhIcRLn+g2Ear1yy5poMrqNf6qwaQn g8DYX2mFOdOaOs5mbXk0LTvvAyO7fcRJxMy0rGf09ss0fIAryVeBdCMXMjbsSMJCvZOf ZP/JKJarvxKjc+dTnqrR5tFXz3tOJHla57MAjyVRhn9pIkPRTSPdWuDob3ITKlO43tde qbkA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:cc :to:dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=vQy41InJs0KcqXV4KXQahMrgu5hlh7apDxapgHG4ejg=; b=b1CPx3BfMnBO2Um9YIw7CyEpjy99uwUkuwLralBG2APsrgEKK/roMSXgmR+OOry/rc YovqjW50juDVnNQa1g8uWYtKFtkG9BkZh6OZR9vEtthHxSyq98PXUIdi3/FKGwXWGBmT rKYt2hFIsKHwIKD7JhxTskVT5TeYBggyT2gYJL3OI5pFPawoV5K4KA/wRipKLfB3G85q 10wNw1tBS7m+WtY2ikV1HhFMfGl8Jl3Pvw5AJsx5CrFs8tp+WiK06PqVH25ooqisw4+M mCO1txUZwwbZRt8RwIUoaxyh8msb9JvksE2yyoL34/TCb3D12w/NahhXAQiaxxm1COHA vAVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=sOxHIIpd; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id d17-20020aa7ce11000000b004a0e0c9a653si6425316edv.599.2023.01.27.14.04.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Jan 2023 14:04:13 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=sOxHIIpd; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2E8BC385802F for ; Fri, 27 Jan 2023 22:03:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2E8BC385802F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1674857038; bh=vQy41InJs0KcqXV4KXQahMrgu5hlh7apDxapgHG4ejg=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=sOxHIIpdaGo5oQahX8T8P83x1cRXUmTdxtyWwdMecNsC/2c9L9mOVD7O+xeIPTFoN YsahG3gmA0VCtXHMoA71SeD3tp+Ab8vRrBI+5O3C3r3u+hUt/MLoLp7bawZheYDMOs IW/r56B72CtuR7ZWrFiDX81nHoU6y0uG7u1wV6pY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org 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 3A2A63858D38 for ; Fri, 27 Jan 2023 22:03:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3A2A63858D38 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-433-4tIgdJlmOpKdobeJoiaJMw-1; Fri, 27 Jan 2023 17:02:54 -0500 X-MC-Unique: 4tIgdJlmOpKdobeJoiaJMw-1 Received: by mail-qt1-f197.google.com with SMTP id m7-20020ac807c7000000b003b80b35c136so2739057qth.5 for ; Fri, 27 Jan 2023 14:02:54 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=vQy41InJs0KcqXV4KXQahMrgu5hlh7apDxapgHG4ejg=; b=KuGGNxA6jn1fGKBJsjIP3tajJO8fJ3lBn0oQ/AiU5p4qGchI36feKlA+Vqq6/kF4z8 SeGIGCsdd6bN0Cit5zSrwRB/ai7FM22fL2lCrdYCgCvZGAfyEduS/2MDc3ebUBUdlSTa aZFNTgEsbWQvJeIaTfZ2wy3YpumJXkchiTpGlO1znT/TTb9dVKxtbsg0GtgFsHtObtPY HAkEqDj2Qw/3szHPUzILtMPOl7K5/h512shALvGsKPwOWC+ZszDUzoX37kCnKX/ueaRA 8pGUuZWJM3Me5kh/t8xnPG5huJJmst9s2hWNIPnXvGGDnQC4SlepwKwapO1aU0UtNtAX QD8A== X-Gm-Message-State: AFqh2krOzSiII1xkh6mka4K4x2T30FCrFj09K7q9hNQE67bM/CJE3R// j/MVSWii9qVO+K9sg72jB2YJIK7UqKIyFVv6qhuS1ghAp/wTq3npuvu097jcKVcQy4Vv+graTSv 8eh7fIWe6xYh9RbrbDJOXBPcAjO4IU9qzQg6DMWo2KqWClvu/7vVZgqWd6T1WtajqcvU= X-Received: by 2002:ac8:6a0f:0:b0:3b6:3542:2b4 with SMTP id t15-20020ac86a0f000000b003b6354202b4mr55954753qtr.43.1674856973172; Fri, 27 Jan 2023 14:02:53 -0800 (PST) X-Received: by 2002:ac8:6a0f:0:b0:3b6:3542:2b4 with SMTP id t15-20020ac86a0f000000b003b6354202b4mr55954714qtr.43.1674856972635; Fri, 27 Jan 2023 14:02:52 -0800 (PST) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id w19-20020ae9e513000000b006f9f3c0c63csm3685947qkf.32.2023.01.27.14.02.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Jan 2023 14:02:52 -0800 (PST) To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH 1/2] c++: make manifestly_const_eval tri-state Date: Fri, 27 Jan 2023 17:02:49 -0500 Message-Id: <20230127220250.1896137-1-ppalka@redhat.com> X-Mailer: git-send-email 2.39.1.348.g5dec958dcf MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.7 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756214910170461428?= X-GMAIL-MSGID: =?utf-8?q?1756214910170461428?= 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; }; 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. */ + +enum class mce_value +{ + /* Treat __builtin_is_constant_evaluated as non-constant. */ + mce_unknown = 0, + /* Fold it to true. */ + mce_true = 1, + /* Fold it to false. */ + 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; From patchwork Fri Jan 27 22:02:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 49702 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp1065011wrn; Fri, 27 Jan 2023 14:03:52 -0800 (PST) X-Google-Smtp-Source: AMrXdXsLmam39F+Fy+tmPJuVVSHqJQinf5pQ3hbfsJdjaY9e0ip++3TTeixsAmGSN0XP9iKBwvtN X-Received: by 2002:a17:907:88c4:b0:86d:d041:b8aa with SMTP id rq4-20020a17090788c400b0086dd041b8aamr45655455ejc.27.1674857032422; Fri, 27 Jan 2023 14:03:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1674857032; cv=none; d=google.com; s=arc-20160816; b=UuIj62GI0bUUg5gttjGB8mbE9BWK5IcrcHgbb9Nr/gzPiEk047xVnzQvcsCg6YYNKA nrK5ILw2gQtQZ2Xf10AX3rAwWY7kVy04X04xeiZPyoQpIZcgX5O0tI7WF2DW1ICOKXpA 7j4GABhTY3VMWoqTSNHRNTxOleSLHB6NntOAtkatexL/+3WrsAdclElHjJYVUEOADtZ+ 50MxcApAdLleJX+zsyjmtWyESJ9SwW7LFEGrll/Rw4jA/Nm8jjcp+KQbL8Js57kElnWT R/pL9ANRHRxHO4jnqzv0p6HioBe9nNR742thcsB+GOLsAffbNLKzQkT8c+vCWR+nMJLG SkrA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=tpmpBDJmZmwFMMuKhea9Ui2HTfYD9fBvNE8qPs5/nsM=; b=Zm0aXakhP0uxvmE1g/9zcXXUl65yC6jEMXDRdIsW09UtnFGDIcINQYNquCIFK/cO5v 7//fEWUW90mx76n1sBm3as3a72uoX8s9k9qtiziIn70pVrM/xhrQEfUD09Nd4KDQRS4T f3vpHa2SMD/IMIcLgkxC8d099YGsx5jJW5AuX5ecnhhItndDq2FKi8TgXoGCpTIwE1hY NmN7tOq1MmyP8lJmpLrFTZeX6vDbMzD2XQcgKojNxmFM3rE/M45394d7M2TyWWU1kGnZ lXGSB8TYJK34NbM3Jg0J48VdUaHREft2HhjNMkjzK6fti1IGFBhUxJPMrNkgD2yFmwu0 WKfw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=kJFuLCNp; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id kb5-20020a170907924500b00877dde5c2a8si5463808ejb.753.2023.01.27.14.03.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Jan 2023 14:03:52 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=kJFuLCNp; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 95CCD38582BC for ; Fri, 27 Jan 2023 22:03:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 95CCD38582BC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1674857020; bh=tpmpBDJmZmwFMMuKhea9Ui2HTfYD9fBvNE8qPs5/nsM=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=kJFuLCNpdtqrQOlKOsnUpGwvOrrcoluMwFVYeE8BhJo/rUC1cuQhWOig981WqdB1n r0cCrPrAEidUnuy1pqnodr4B1ff6DKpoJQFo45QaJq9xR6Hhr6FC8u1apXX6fMIsUc PqADpiRxssaQ0YZl/mTYRJFPTeQAajt8UAsJQ3Cs= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org 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 498583858D20 for ; Fri, 27 Jan 2023 22:02:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 498583858D20 Received: from mail-qv1-f69.google.com (mail-qv1-f69.google.com [209.85.219.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-300-bnGAyUf3M7CCSZvaVF-0uA-1; Fri, 27 Jan 2023 17:02:55 -0500 X-MC-Unique: bnGAyUf3M7CCSZvaVF-0uA-1 Received: by mail-qv1-f69.google.com with SMTP id jh2-20020a0562141fc200b004c74bbb0affso3507567qvb.21 for ; Fri, 27 Jan 2023 14:02:55 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tpmpBDJmZmwFMMuKhea9Ui2HTfYD9fBvNE8qPs5/nsM=; b=nLkQLj4C+AC/URujpfEj23b2X+/QRDWvFpNMhsc5u9woKrHxqULIymQG2RhcBmFT47 j1Ej8cw7IUEbo+H2DhCa3MeyxzWJar6nD46ItEIDGXzQEId6o6+M006oN+iHygXE+bVZ UA71W/J7pb8qhnp8/u9eMdYc0NmX6BPuQH9HSczuQun/7de4Mp4tiE6fYPBZEIiYOD1H bjrXTwKkBMnerAjkMMMVPziFi8VtG/Ge1oosz6QER4moMcpsHUYlPy0ijFGydF8Xoy8T ar+2ZHD5ub0LfiEem6Z6hf964GPAVqwj1I0eItZfbY3ECFmVi3azKZnmgmbBXepzV2SG 56nQ== X-Gm-Message-State: AO0yUKXRr6yGr/fpo0ERrXUaSuEEohfjnN7sjxyLcJVGKzyh66XsM02j lOKZnyQks0AUiZAeLWV/jkjloBxp9zwTAlGaVGBy93b0cGnfRelsR9FkJBSIblOMEIcx08S+vvb A4i5zmMqc1axAD2WoGeREHOTHPfm2tXGGWqdFfrrkO9euXeRgRH/X+G3apyWYEGeZ9E0= X-Received: by 2002:a05:622a:391:b0:3b6:33bc:f6bc with SMTP id j17-20020a05622a039100b003b633bcf6bcmr806056qtx.10.1674856973888; Fri, 27 Jan 2023 14:02:53 -0800 (PST) X-Received: by 2002:a05:622a:391:b0:3b6:33bc:f6bc with SMTP id j17-20020a05622a039100b003b633bcf6bcmr806014qtx.10.1674856973465; Fri, 27 Jan 2023 14:02:53 -0800 (PST) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id w19-20020ae9e513000000b006f9f3c0c63csm3685947qkf.32.2023.01.27.14.02.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Jan 2023 14:02:53 -0800 (PST) To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH 2/2] c++: speculative constexpr and is_constant_evaluated [PR108243] Date: Fri, 27 Jan 2023 17:02:50 -0500 Message-Id: <20230127220250.1896137-2-ppalka@redhat.com> X-Mailer: git-send-email 2.39.1.348.g5dec958dcf In-Reply-To: <20230127220250.1896137-1-ppalka@redhat.com> References: <20230127220250.1896137-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.7 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756214887404895477?= X-GMAIL-MSGID: =?utf-8?q?1756214887404895477?= This PR illustrates that __builtin_is_constant_evaluated currently acts as an optimization barrier for our speculative constexpr evaluation, since we don't want to prematurely fold the builtin to false if the expression in question would be later manifestly constant evaluated (in which case it must be folded to true). This patch fixes this by permitting __builtin_is_constant_evaluated to get folded as false during cp_fold_function, since at that point we're sure we're doing manifestly constant evaluation. To that end we add a flags parameter to cp_fold that controls what mce_value the CALL_EXPR case passes to maybe_constant_value. bootstrapped and rgetsted no x86_64-pc-linux-gnu, does this look OK for trunk? PR c++/108243 gcc/cp/ChangeLog: * cp-gimplify.cc (enum fold_flags): Define. (cp_fold_data::genericize): Replace this data member with ... (cp_fold_data::fold_flags): ... this. (cp_fold_r): Adjust cp_fold_data use and cp_fold_calls. (cp_fold_function): Likewise. (cp_fold_maybe_rvalue): Likewise. (cp_fully_fold_init): Likewise. (cp_fold): Add fold_flags parameter. Don't cache if flags isn't empty. : Pass mce_false to maybe_constant_value if if ff_genericize is set. gcc/testsuite/ChangeLog: * g++.dg/opt/pr108243.C: New test. --- gcc/cp/cp-gimplify.cc | 76 ++++++++++++++++++----------- gcc/testsuite/g++.dg/opt/pr108243.C | 29 +++++++++++ 2 files changed, 76 insertions(+), 29 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/pr108243.C diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc index a35cedd05cc..d023a63768f 100644 --- a/gcc/cp/cp-gimplify.cc +++ b/gcc/cp/cp-gimplify.cc @@ -43,12 +43,20 @@ along with GCC; see the file COPYING3. If not see #include "omp-general.h" #include "opts.h" +/* Flags for cp_fold and cp_fold_r. */ + +enum fold_flags { + ff_none = 0, + /* Whether we're being called from cp_fold_function. */ + ff_genericize = 1 << 0, +}; + /* Forward declarations. */ static tree cp_genericize_r (tree *, int *, void *); static tree cp_fold_r (tree *, int *, void *); static void cp_genericize_tree (tree*, bool); -static tree cp_fold (tree); +static tree cp_fold (tree, fold_flags); /* Genericize a TRY_BLOCK. */ @@ -996,9 +1004,8 @@ struct cp_genericize_data struct cp_fold_data { hash_set pset; - bool genericize; // called from cp_fold_function? - - cp_fold_data (bool g): genericize (g) {} + fold_flags flags; + cp_fold_data (fold_flags flags): flags (flags) {} }; static tree @@ -1039,7 +1046,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) break; } - *stmt_p = stmt = cp_fold (*stmt_p); + *stmt_p = stmt = cp_fold (*stmt_p, data->flags); if (data->pset.add (stmt)) { @@ -1119,12 +1126,12 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) here rather than in cp_genericize to avoid problems with the invisible reference transition. */ case INIT_EXPR: - if (data->genericize) + if (data->flags & ff_genericize) cp_genericize_init_expr (stmt_p); break; case TARGET_EXPR: - if (data->genericize) + if (data->flags & ff_genericize) cp_genericize_target_expr (stmt_p); /* Folding might replace e.g. a COND_EXPR with a TARGET_EXPR; in @@ -1157,7 +1164,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) void cp_fold_function (tree fndecl) { - cp_fold_data data (/*genericize*/true); + cp_fold_data data (ff_genericize); cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &data, NULL); } @@ -2375,7 +2382,7 @@ cp_fold_maybe_rvalue (tree x, bool rval) { while (true) { - x = cp_fold (x); + x = cp_fold (x, ff_none); if (rval) x = mark_rvalue_use (x); if (rval && DECL_P (x) @@ -2434,7 +2441,7 @@ cp_fully_fold_init (tree x) if (processing_template_decl) return x; x = cp_fully_fold (x); - cp_fold_data data (/*genericize*/false); + cp_fold_data data (ff_none); cp_walk_tree (&x, cp_fold_r, &data, NULL); return x; } @@ -2469,7 +2476,7 @@ clear_fold_cache (void) Function returns X or its folded variant. */ static tree -cp_fold (tree x) +cp_fold (tree x, fold_flags flags) { tree op0, op1, op2, op3; tree org_x = x, r = NULL_TREE; @@ -2490,8 +2497,11 @@ cp_fold (tree x) if (fold_cache == NULL) fold_cache = hash_map::create_ggc (101); - if (tree *cached = fold_cache->get (x)) - return *cached; + bool cache_p = (flags == ff_none); + + if (cache_p) + if (tree *cached = fold_cache->get (x)) + return *cached; uid_sensitive_constexpr_evaluation_checker c; @@ -2526,7 +2536,7 @@ cp_fold (tree x) Don't create a new tree if op0 != TREE_OPERAND (x, 0), the folding of the operand should be in the caches and if in cp_fold_r it will modify it in place. */ - op0 = cp_fold (TREE_OPERAND (x, 0)); + op0 = cp_fold (TREE_OPERAND (x, 0), flags); if (op0 == error_mark_node) x = error_mark_node; break; @@ -2571,7 +2581,7 @@ cp_fold (tree x) { tree p = maybe_undo_parenthesized_ref (x); if (p != x) - return cp_fold (p); + return cp_fold (p, flags); } goto unary; @@ -2763,8 +2773,8 @@ cp_fold (tree x) case COND_EXPR: loc = EXPR_LOCATION (x); op0 = cp_fold_rvalue (TREE_OPERAND (x, 0)); - op1 = cp_fold (TREE_OPERAND (x, 1)); - op2 = cp_fold (TREE_OPERAND (x, 2)); + op1 = cp_fold (TREE_OPERAND (x, 1), flags); + op2 = cp_fold (TREE_OPERAND (x, 2), flags); if (TREE_CODE (TREE_TYPE (x)) == BOOLEAN_TYPE) { @@ -2854,7 +2864,7 @@ cp_fold (tree x) { if (!same_type_p (TREE_TYPE (x), TREE_TYPE (r))) r = build_nop (TREE_TYPE (x), r); - x = cp_fold (r); + x = cp_fold (r, flags); break; } } @@ -2908,7 +2918,7 @@ cp_fold (tree x) int m = call_expr_nargs (x); for (int i = 0; i < m; i++) { - r = cp_fold (CALL_EXPR_ARG (x, i)); + r = cp_fold (CALL_EXPR_ARG (x, i), flags); if (r != CALL_EXPR_ARG (x, i)) { if (r == error_mark_node) @@ -2931,7 +2941,7 @@ cp_fold (tree x) if (TREE_CODE (r) != CALL_EXPR) { - x = cp_fold (r); + x = cp_fold (r, flags); break; } @@ -2944,7 +2954,15 @@ cp_fold (tree x) constant, but the call followed by an INDIRECT_REF is. */ if (callee && DECL_DECLARED_CONSTEXPR_P (callee) && !flag_no_inline) - r = maybe_constant_value (x); + { + mce_value manifestly_const_eval = mce_unknown; + if (flags & ff_genericize) + /* At genericization time it's safe to fold + __builtin_is_constant_evaluated to false. */ + manifestly_const_eval = mce_false; + r = maybe_constant_value (x, /*decl=*/NULL_TREE, + manifestly_const_eval); + } optimize = sv; if (TREE_CODE (r) != CALL_EXPR) @@ -2971,7 +2989,7 @@ cp_fold (tree x) vec *nelts = NULL; FOR_EACH_VEC_SAFE_ELT (elts, i, p) { - tree op = cp_fold (p->value); + tree op = cp_fold (p->value, flags); if (op != p->value) { if (op == error_mark_node) @@ -3002,7 +3020,7 @@ cp_fold (tree x) for (int i = 0; i < n; i++) { - tree op = cp_fold (TREE_VEC_ELT (x, i)); + tree op = cp_fold (TREE_VEC_ELT (x, i), flags); if (op != TREE_VEC_ELT (x, i)) { if (!changed) @@ -3019,10 +3037,10 @@ cp_fold (tree x) case ARRAY_RANGE_REF: loc = EXPR_LOCATION (x); - op0 = cp_fold (TREE_OPERAND (x, 0)); - op1 = cp_fold (TREE_OPERAND (x, 1)); - op2 = cp_fold (TREE_OPERAND (x, 2)); - op3 = cp_fold (TREE_OPERAND (x, 3)); + op0 = cp_fold (TREE_OPERAND (x, 0), flags); + op1 = cp_fold (TREE_OPERAND (x, 1), flags); + op2 = cp_fold (TREE_OPERAND (x, 2), flags); + op3 = cp_fold (TREE_OPERAND (x, 3), flags); if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1) @@ -3050,7 +3068,7 @@ cp_fold (tree x) /* A SAVE_EXPR might contain e.g. (0 * i) + (0 * j), which, after folding, evaluates to an invariant. In that case no need to wrap this folded tree with a SAVE_EXPR. */ - r = cp_fold (TREE_OPERAND (x, 0)); + r = cp_fold (TREE_OPERAND (x, 0), flags); if (tree_invariant_p (r)) x = r; break; @@ -3069,7 +3087,7 @@ cp_fold (tree x) copy_warning (x, org_x); } - if (!c.evaluation_restricted_p ()) + if (cache_p && !c.evaluation_restricted_p ()) { fold_cache->put (org_x, x); /* Prevent that we try to fold an already folded result again. */ diff --git a/gcc/testsuite/g++.dg/opt/pr108243.C b/gcc/testsuite/g++.dg/opt/pr108243.C new file mode 100644 index 00000000000..4c45dbba13c --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr108243.C @@ -0,0 +1,29 @@ +// PR c++/108243 +// { dg-do compile { target c++11 } } +// { dg-additional-options "-O -fdump-tree-original" } + +constexpr int foo() { + return __builtin_is_constant_evaluated() + 1; +} + +#if __cpp_if_consteval +constexpr int bar() { + if consteval { + return 5; + } else { + return 4; + } +} +#endif + +int p, q; + +int main() { + p = foo(); +#if __cpp_if_consteval + q = bar(); +#endif +} + +// { dg-final { scan-tree-dump-not "= foo" "original" } } +// { dg-final { scan-tree-dump-not "= bar" "original" } }