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 BC1F13858433 for ; Thu, 16 Dec 2021 21:14:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BC1F13858433 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.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-155-YowwCK52P6ycP3od9E-p1g-1; Thu, 16 Dec 2021 16:14:14 -0500 X-MC-Unique: YowwCK52P6ycP3od9E-p1g-1 Received: by mail-qv1-f69.google.com with SMTP id ib7-20020a0562141c8700b0040812bc4425so511083qvb.16 for ; Thu, 16 Dec 2021 13:14:14 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=6otqDX1SNPJEMbeB+6egYFR8juR7QouuLHCUhnFVQWE=; b=Hsk5febOkxpcn0Wfbc32HX6uA/Yo2CxMoB6T8jb7mcIETurrZo/hLSEJMlJf98aHZS V9+zmv9WVsXqXYfaxC7CT6mrJnSx3lFpvd3+ZTqdKRt2v5UUGnUZ0HmV3VxbjSLxbUlB vZV0udAFYMVTmPuDCIVqYseSbwsuoOTxDYMAJAOEx5xLxeypYFoRAJcxLE4VWFAaBviq 82plfvc+ammZJH0fL4Kks9dsWiIcPQwANfhtiT+qulj9DTDna3NUAaeBrfPsPL5uaJJ7 AcEhsnd/pkbpbxTsYDji10Vgx2b/ACSHHC/ZHUoz77U/1daf6mFO2TW+fptKrMRohJOf UFgQ== X-Gm-Message-State: AOAM530FF59LQsL2VmfgkIEZGzvN+LB4pb1WXJMYEVtJsF4wuwwo3p3G VSnB8a/Y8mTbeuYFTicDmjx0zAD8il/bSzQrP2yMJfAld+D2eozmRXHcEYJ6h98ZtYc8bFelLUD Fw/+M2MgTALarP9Fz6g== X-Received: by 2002:a05:620a:1904:: with SMTP id bj4mr13338641qkb.536.1639689253176; Thu, 16 Dec 2021 13:14:13 -0800 (PST) X-Google-Smtp-Source: ABdhPJwHw6QH1b1kVx3Wg09DR2iM08m2H3+rwITqEULEI+wNa6YmYDnCO0xKJu46XhKz/5ahZHg/9A== X-Received: by 2002:a05:620a:1904:: with SMTP id bj4mr13338619qkb.536.1639689252800; Thu, 16 Dec 2021 13:14:12 -0800 (PST) Received: from [192.168.1.149] (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 n13sm3934958qkp.19.2021.12.16.13.14.11 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 16 Dec 2021 13:14:12 -0800 (PST) Message-ID: <8eec4dde-3e3d-a1bd-8888-165e69fbffbe@redhat.com> Date: Thu, 16 Dec 2021 16:14:11 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.4.0 Subject: Re: [PATCH] c++: nested lambda capturing a capture proxy, part 2 [PR94376] To: Patrick Palka Cc: gcc-patches@gcc.gnu.org References: <20211215203612.4095222-1-ppalka@redhat.com> <0594bc89-b458-13f2-047f-745da5ff23ca@redhat.com> From: Jason Merrill In-Reply-To: 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=-13.2 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_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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-List-Received-Date: Thu, 16 Dec 2021 21:14:18 -0000 On 12/16/21 11:28, Patrick Palka wrote: > On Wed, 15 Dec 2021, Jason Merrill wrote: > >> On 12/15/21 15:36, Patrick Palka wrote: >>> The r12-5403 fix apparently doesn't handle the case where the inner >>> lambda explicitly rather implicitly captures the capture proxy from >>> the outer lambda, and so we still reject the first example in the >>> testcase below. >>> >>> The reason is that compared to an implicit capture, the effective >>> initializer for an explicit capture is wrapped in a location wrapper >>> (pointing to the source location of the explicit capture), and this >>> wrapper foils the is_capture_proxy check. The simplest fix appears to >>> be to strip location wrappers accordingly. >>> >>> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for >>> trunk? >>> >>> PR c++/94376 >>> >>> gcc/cp/ChangeLog: >>> >>> * lambda.c (lambda_capture_field_type): Strip location wrappers >>> before checking for a capture proxy. >> >> I think either is_capture_proxy should strip location wrappers or >> gcc_checking_assert that it doesn't see one. > > Good idea, here's v2 which adds an assert to is_capture_proxy. Only one > other caller, mark_const_cap_r, had to be adjusted. OK. > -- >8 -- > > The r12-5403 fix apparently doesn't handle the case where the inner > lambda explicitly rather implicitly captures the capture proxy from > the outer lambda, which causes us to reject the first example in the > testcase below. > > This is because compared to an implicit capture, the effective initializer > for an explicit capture is wrapped in a location wrapper (pointing to the > capture list), and this wrapper foils the is_capture_proxy check added in > r12-5403. > > The simplest fix appears to be to strip location wrappers accordingly > before checking is_capture_proxy. To help prevent against other > occurrences of this kind of bug, this patch also makes is_capture_proxy > assert it doesn't see a location wrapper. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk? > > PR c++/94376 > > gcc/cp/ChangeLog: > > * lambda.c (lambda_capture_field_type): Strip location wrappers > before checking for a capture proxy. > (is_capture_proxy): Assert that we don't see a location wrapper. > (mark_const_cap_r): Don't call is_constant_capture_proxy on a > location wrapper. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp0x/lambda/lambda-nested9a.C: New test. > --- > gcc/cp/lambda.c | 7 ++++ > .../g++.dg/cpp0x/lambda/lambda-nested9a.C | 42 +++++++++++++++++++ > 2 files changed, 49 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9a.C > > diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c > index c39a2bca416..d14e12c48f0 100644 > --- a/gcc/cp/lambda.c > +++ b/gcc/cp/lambda.c > @@ -221,6 +221,7 @@ lambda_capture_field_type (tree expr, bool explicit_init_p, > } > else > { > + STRIP_ANY_LOCATION_WRAPPER (expr); > if (!by_reference_p && is_capture_proxy (expr)) > { > /* When capturing by-value another capture proxy from an enclosing > @@ -246,6 +247,10 @@ lambda_capture_field_type (tree expr, bool explicit_init_p, > bool > is_capture_proxy (tree decl) > { > + /* Location wrappers should be stripped or otherwise handled by the > + caller before using this predicate. */ > + gcc_checking_assert (!location_wrapper_p (decl)); > + > return (VAR_P (decl) > && DECL_HAS_VALUE_EXPR_P (decl) > && !DECL_ANON_UNION_VAR_P (decl) > @@ -1496,6 +1501,8 @@ mark_const_cap_r (tree *t, int *walk_subtrees, void *data) > *walk_subtrees = 0; > } > } > + else if (location_wrapper_p (*t)) > + /* is_capture_proxy dislikes location wrappers. */; > else if (is_constant_capture_proxy (*t)) > var = DECL_CAPTURED_VARIABLE (*t); > > diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9a.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9a.C > new file mode 100644 > index 00000000000..d62f8f0c952 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9a.C > @@ -0,0 +1,42 @@ > +// PR c++/94376 > +// Like lambda-nested9.C but using explicit captures in the inner lambda. > +// { dg-do compile { target c++11 } } > + > +int main() { > + // We used to incorrectly reject the first two cases. > + int i = 0; > + [=] () { > + [i] () mutable { > + ++i; > + }; > + }; > + > +#if __cpp_init_captures > + [j=0] () { > + [j] () mutable { > + ++j; > + }; > + }; > +#endif > + > + [=] () { > + [&i] () mutable { > + ++i; // { dg-error "read-only" } > + }; > + }; > + > + const int j = 0; > + [=] () { > + [j] () mutable { > + ++j; // { dg-error "read-only" } > + }; > + }; > + > +#if __cpp_init_captures > + [j=0] () { > + [&j] () mutable { > + ++j; // { dg-error "read-only" "" { target c++14 } } > + }; > + }; > +#endif > +}