From patchwork Fri Dec 9 21:57:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 61738 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1B8893844B1D for ; Fri, 9 Dec 2022 21:58:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1B8893844B1D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1670623084; bh=CBPu+4fxgsg/chdym9u1SoSBfh4+CvEMLUVZw0BdTfs=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=n6CEdB1z8xUIUPm0F13xXfSUNXINGayUGp2uJpPvSnxHIUhfaVk/eTeaSpO6P/vVu zf7XHvAP1kQ35cHQxS/GNtoZAUmvu55D3F5NB+gjfJ+D8LwH2UWYeedRVObUboBgdD OSVoCnFSKk2fVSfCQSeqnXl2/PU+G5PYN6/Htjm8= 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 587933844B38 for ; Fri, 9 Dec 2022 21:57:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 587933844B38 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-527-pADMkgRyPX2tpmoe2jlaKw-1; Fri, 09 Dec 2022 16:57:33 -0500 X-MC-Unique: pADMkgRyPX2tpmoe2jlaKw-1 Received: by mail-qv1-f69.google.com with SMTP id q17-20020a056214019100b004b1d3c9f3acso5618331qvr.0 for ; Fri, 09 Dec 2022 13:57:33 -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=CBPu+4fxgsg/chdym9u1SoSBfh4+CvEMLUVZw0BdTfs=; b=cX62hTykLzppwuoDig81xRn1lDjYUSfM8Yj9BBHF1AOFFPjw6NPNwp05+RrcbzKSN8 Mj4XGSGnTR+7qV92BB+b+3RfkSmeThx8EI1gtngpSrszI9SloVVAIKw640KeBCx2LrWP eGQKsorR5b8tcuh7bXnb9h7nvi3Nvrkw8br+mBpSlfW8bwUP0Bg4jv/KdqOfaGea7A3B yLbHwR6CptkTXHgjE1nTrwiQ9QSu5B5xkHsTiAI8hunfiAKBEFOYNh61tRjRhAIkAkQx DFYXY6l08qxp8QGVgdfTP2LS9mpNtYAdTpNhCL2Gs2IyTdmQCuB5FlJidzun3+fkXnk8 Sw3g== X-Gm-Message-State: ANoB5plmblqdr356dW+GsSRC5ZHwepdzs9ELCNU739mNfa9pHuG6EEOZ pkBAu+Hojq69QRVQVntbgybnRDX5MFGYGXasY2AkYrydt2PX6hhjNJuV4NM6swjsTPNEyccGv30 /qu49DX1qbLbw8+7ZlgX4jJRYBb+CPBYuMBis6CHEZ0nFHF7pdkv099cJODQh9UC/YKE= X-Received: by 2002:a05:622a:5084:b0:3a8:47e:3683 with SMTP id fp4-20020a05622a508400b003a8047e3683mr4221331qtb.56.1670623052755; Fri, 09 Dec 2022 13:57:32 -0800 (PST) X-Google-Smtp-Source: AA0mqf4zmSHjRjSl1asYVnFiGe/5LEMDDgIhtTTR219CVZcKB0EfGv+WVWJw/VyK/WuZLVDLURIoiw== X-Received: by 2002:a05:622a:5084:b0:3a8:47e:3683 with SMTP id fp4-20020a05622a508400b003a8047e3683mr4221309qtb.56.1670623052427; Fri, 09 Dec 2022 13:57:32 -0800 (PST) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id i22-20020a05620a075600b006bb82221013sm772114qki.0.2022.12.09.13.57.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Dec 2022 13:57:31 -0800 (PST) To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH] c++: extract_local_specs and unevaluated contexts [PR100295] Date: Fri, 9 Dec 2022 16:57:20 -0500 Message-Id: <20221209215720.3142097-1-ppalka@redhat.com> X-Mailer: git-send-email 2.39.0.rc2 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Here during partial instantiation of the constexpr if, extra_local_specs walks the statement looking for local specializations within to save and possibly capture. However, we're thwarted by the fact that 'ts' first appears inside an unevaluated context, and so the calls to process_outer_var_ref for its local specializations are a no-op. And since we walk each tree exactly once, we end up not capturing them despite it later occuring in an evaluated context. This patch fixes this by making extract_local_specs walk evaluated contexts first before walking unevaluated contexts. We could probably get away with not walking unevaluated contexts at all, but this approach seems safer. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk/12? PR c++/100295 PR c++/107579 gcc/cp/ChangeLog: * pt.cc (el_data::skip_unevaluated_operands): New data member. (extract_locals_r): If skip_unevaluated_operands is true, don't walk into unevaluated contexts. (extract_local_specs): Walk the pattern twice, first with skip_unevaluated_operands true followed by it set to false. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/constexpr-if-lambda5.C: New test. --- gcc/cp/pt.cc | 19 ++++++++++++++++++- .../g++.dg/cpp1z/constexpr-if-lambda5.C | 15 +++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda5.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index d05a49b1c11..2b22bf14c53 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -13015,17 +13015,26 @@ public: /* List of local_specializations used within the pattern. */ tree extra; tsubst_flags_t complain; + /* True iff we don't want to walk into unevaluated contexts. */ + bool skip_unevaluated_operands = false; el_data (tsubst_flags_t c) : extra (NULL_TREE), complain (c) {} }; static tree -extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data_) +extract_locals_r (tree *tp, int *walk_subtrees, void *data_) { el_data &data = *reinterpret_cast(data_); tree *extra = &data.extra; tsubst_flags_t complain = data.complain; + if (data.skip_unevaluated_operands + && unevaluated_p (TREE_CODE (*tp))) + { + *walk_subtrees = 0; + return NULL_TREE; + } + if (TYPE_P (*tp) && typedef_variant_p (*tp)) /* Remember local typedefs (85214). */ tp = &TYPE_NAME (*tp); @@ -13117,6 +13126,14 @@ static tree extract_local_specs (tree pattern, tsubst_flags_t complain) { el_data data (complain); + /* Walk the pattern twice, ignoring unevaluated operands the first time + around, so that if a local specialization appears in both an + evaluated and unevaluated context we prefer to process it in the + former context (since e.g. process_outer_var_ref is a no-op inside + an unevaluated context). */ + data.skip_unevaluated_operands = true; + cp_walk_tree (&pattern, extract_locals_r, &data, &data.visited); + data.skip_unevaluated_operands = false; cp_walk_tree (&pattern, extract_locals_r, &data, &data.visited); return data.extra; } diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda5.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda5.C new file mode 100644 index 00000000000..d2bf0221743 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda5.C @@ -0,0 +1,15 @@ +// PR c++/100295 +// { dg-do compile { target c++17 } } + +template +void f(Ts... ts) { + auto lambda = [=](auto x) { + if constexpr (sizeof((ts+x) + ...) != 0) + (..., ts); + }; + lambda(0); +} + +int main() { + f(0, 'a'); +}