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 95BC63858C50 for ; Sat, 18 Mar 2023 13:50:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 95BC63858C50 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=1679147458; 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=qAK8MloogGkx+bhXK/rMSyfNF+laIKd+n67hmTjNrHY=; b=KzT7zSrUNhZTt1WW0EzjtQIrokp5DSjpMgJNe19SDmyr14cHKNzNKKDbn3b89Rw/WOkeFi eD2dygzpZp2u65177iA5qopvOnlOs2DOquQIlj+1ET0t2BCBdFRQdZWpnsuYUE5udRoZ9f kyHmwqdmTY0KIS2s78YRv+YTU+VCYLM= Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-277-3gB_P6ZGNxW2HaR4dAfr0g-1; Sat, 18 Mar 2023 09:50:56 -0400 X-MC-Unique: 3gB_P6ZGNxW2HaR4dAfr0g-1 Received: by mail-qt1-f199.google.com with SMTP id f36-20020a05622a1a2400b003deb2fa544bso138997qtb.0 for ; Sat, 18 Mar 2023 06:50:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679147456; 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=qAK8MloogGkx+bhXK/rMSyfNF+laIKd+n67hmTjNrHY=; b=reFkSEtoRYEllMAefMVSNVp7Hc7bkYt57gMGmavbLoCkfM0IiTIKTnnjZUDKeqC+NA 6y2WnpBe3sualIV60B96LYclZNVTZMxQm/IvJ/3anOG61HledsTcJiPC4lkMC1gJczeR cvxH8cMiIr0rNUSMo19qb/qmUBw5BsXI1NBBDKu19NWthxpPJHJe4aSUvQFjspkB/JjT oDGLbLE6Jbns4jmu3IoRKlyDIEZ6gERODRWBFsVH2N0tEmTlLMy/CDKSs+DK6LL0RiwY 3vfS3hJFLiJHTroRNsCz03bm4ODfK1ydwUeXmq15PRrzNh+7etSJYmt/yzAPM0R1+GcT 7HQA== X-Gm-Message-State: AO0yUKVLgL5ZCRb49Dp3hZLgvl6DdI7/IapSCiPrl8yBOCYQCUUFbLSW wpfRI6KdNH2yrkWbNmET1xu8Dxk9vYD/Afpupa/tJpDQJL0l+rpqyRJZ5pUiPTJo93vuvPgCRfb p9OAOX5+RK9suuJ2LYg== X-Received: by 2002:a05:622a:1aa0:b0:3b8:6d3a:5ed4 with SMTP id s32-20020a05622a1aa000b003b86d3a5ed4mr18248981qtc.67.1679147456151; Sat, 18 Mar 2023 06:50:56 -0700 (PDT) X-Google-Smtp-Source: AK7set/PUh5Af61f1w15B05PSUynKfymp6rwxW3v8egImf/kRDLJgYYzkZdtQCrNqmJC0TdZkiInAQ== X-Received: by 2002:a05:622a:1aa0:b0:3b8:6d3a:5ed4 with SMTP id s32-20020a05622a1aa000b003b86d3a5ed4mr18248959qtc.67.1679147455822; Sat, 18 Mar 2023 06:50:55 -0700 (PDT) Received: from [192.168.1.130] (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id w8-20020a05620a424800b0073b587194d0sm3697405qko.104.2023.03.18.06.50.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Mar 2023 06:50:55 -0700 (PDT) From: Patrick Palka X-Google-Original-From: Patrick Palka Date: Sat, 18 Mar 2023 09:50:54 -0400 (EDT) To: Jason Merrill cc: gcc-patches@gcc.gnu.org Subject: Re: [pushed] c++: constant, array, lambda, template [PR108975] In-Reply-To: <20230317233249.1406928-1-jason@redhat.com> Message-ID: <162739c5-32da-bc17-bae5-47df5d89be59@idea> References: <20230317233249.1406928-1-jason@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 Fri, 17 Mar 2023, Jason Merrill via Gcc-patches wrote: > Tested x86_64-pc-linux-gnu, applying to trunk. > > -- 8< -- > > When a lambda refers to a constant local variable in the enclosing scope, we > tentatively capture it, but if we end up pulling out its constant value, we > go back at the end of the lambda and prune any unneeded captures. Here > while parsing the template we decided that the dim capture was unneeded, > because we folded it away, but then we brought back the use in the template > trees that try to preserve the source representation with added type info. > So then when we tried to instantiate that use, we couldn't find what it was > trying to use, and crashed. > > Fixed by not trying to prune when parsing a template; we'll prune at > instantiation time. > > PR c++/108975 > > gcc/cp/ChangeLog: > > * lambda.cc (prune_lambda_captures): Don't bother in a template. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp0x/lambda/lambda-const11.C: New test. > --- > gcc/cp/lambda.cc | 3 +++ > gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const11.C | 14 ++++++++++++++ > 2 files changed, 17 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const11.C > > diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc > index 212990a21bf..9925209b2ed 100644 > --- a/gcc/cp/lambda.cc > +++ b/gcc/cp/lambda.cc > @@ -1760,6 +1760,9 @@ prune_lambda_captures (tree body) > if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) == CPLD_NONE) > /* No default captures, and we don't prune explicit captures. */ > return; > + /* Don't bother pruning in a template, we'll prune at instantiation time. */ > + if (dependent_type_p (TREE_TYPE (lam))) > + return; > > hash_map const_vars; > > diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const11.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const11.C > new file mode 100644 > index 00000000000..26af75bf132 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const11.C > @@ -0,0 +1,14 @@ > +// PR c++/108975 > +// { dg-do compile { target c++11 } } > + > +template > +void f() { > + constexpr int dim = 1; > + auto l = [&] { > + int n[dim * 1]; > + }; > + // In f, we shouldn't actually capture dim. > + static_assert (sizeof(l) == 1, ""); > +} > + > +template void f(); Sadly I think more is needed to fix the generic lambda case, we still crash for: template void f() { constexpr int dim = 1; auto l = [&] (auto) { int n[dim * 1]; }; l(0); // In f, we shouldn't actually capture dim. static_assert (sizeof(l) == 1, ""); } template void f(); It seems prune_lambda_captures doesn't thoroughly walk the lambda body, and so fails to find all uses of constant captures such as in 'int n[dim * 1]' or 'using type = decltype(g())' (in the original testcase the constant capture use occurred inside an alias declaration). I guess generic lambdas are special in that their body is always templated and so fewer constant captures are folded away by instantiation time. So they are more sensitive to incomplete walking by prune_lambda_captures.