From patchwork Tue Nov 2 18:06:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 46963 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 9573D385842A for ; Tue, 2 Nov 2021 18:07:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9573D385842A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1635876452; bh=O4Ds4H0LJcaxIbC0aC1kz2q8y3Hc/thUvf/++4qPOU8=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=YopVThtf10ve63HKq3K2fL1zfEPZQ+BODU5RjlPWvb5+5x6QoRi3SYXaimYZ+B55e pTi8+OgGII/EqKkr1HvEe48PaeJKO/FXRYhe7nAz5iUMvY8pGYVtPo0yuN2BvOl527 jWBou/l8ApCX6w6K+cpZWvk29fAvHO2bBvXAQDTs= 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 3DF2F3858007 for ; Tue, 2 Nov 2021 18:06:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3DF2F3858007 Received: from mail-qv1-f69.google.com (mail-qv1-f69.google.com [209.85.219.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-576-09SRYG2dPLyBRK51tOLS7g-1; Tue, 02 Nov 2021 14:06:57 -0400 X-MC-Unique: 09SRYG2dPLyBRK51tOLS7g-1 Received: by mail-qv1-f69.google.com with SMTP id n18-20020a0cbe92000000b00384d0c98fccso20672135qvi.2 for ; Tue, 02 Nov 2021 11:06:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=O4Ds4H0LJcaxIbC0aC1kz2q8y3Hc/thUvf/++4qPOU8=; b=fxXtgOZaHRJGjei+AM3u8LHo1qijUM0wox5wLhx8D8EIZVkF4t9hpGHQw41/m/BWi4 s5IHiyfJo48cuawlnyFDCgeuxFbIgrJOijOYKbjdMhXZsRGFPnBM0SedleFo1H/y7vVB h3ZVMSJWI6q7OTC7ZBnCJSWMjBTB62d+yirOyC20l0ZuKUy4zFxflR46kDdVpFLlrlt5 HA2WURMfhEtunaumoPR0HRTSO/h48bRsQyRPR9okl72uX+bbpqTNZH/xibWE38xKDK68 aeiC+pSfMmE25oPL+O/n+u5R8wDF4+FuM8Rcpd+OHd6nSYNc08k3uALeLz6Zqw8YCud9 zpew== X-Gm-Message-State: AOAM5313JWvQ/cYrYSefg7GP1GWLJWm8dHQMNR8JQsjKhi1ZLB6pYMao I+0K7GyNulabqYsJM/MSvHFho+3ljkYoooEFnJwQ/QD3CRgnCr6fUBFP6KqexmQidAchzBoGFqK QPiTCXwu9jIlFk85a2TDwUwUsgppYMiAtuPuoBR4PwYiMHwyX5AVJJaTSwzaZqCJ6Hs8= X-Received: by 2002:ac8:598a:: with SMTP id e10mr5867467qte.102.1635876416269; Tue, 02 Nov 2021 11:06:56 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyIrLUliuNYJHGnJhBxrUvyO0fSIKJsv4G0cHi3YOPwusWmJ8xcAMnJf4JC1e081aWx+Oks0A== X-Received: by 2002:ac8:598a:: with SMTP id e10mr5867420qte.102.1635876415855; Tue, 02 Nov 2021 11:06:55 -0700 (PDT) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id az39sm3821455qkb.2.2021.11.02.11.06.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Nov 2021 11:06:55 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: nested lambda capturing a capture proxy [PR94376] Date: Tue, 2 Nov 2021 14:06:53 -0400 Message-Id: <20211102180653.1146172-1-ppalka@redhat.com> X-Mailer: git-send-email 2.34.0.rc0.19.g0cddd84c9f MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-16.0 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_LOW, RCVD_IN_MSPIKE_H2, 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-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 when determining the type of the FIELD_DECL for the by-value capture of 'i' in the inner lambda, we incorrectly give it the type const int instead of int since the effective initializer is the proxy for the outer capture, and this proxy is const qualified since the outer lambda is non-mutable. This patch fixes this by handling capturing of capture proxies specially in lambda_capture_field_type, namely we instead consider the type of their FIELD_DECL which unlike the proxy has the true cv-quals of the captured entity. 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): Simplify by handling the is_this case first and specially. When capturing by-value a capture proxy, consider the type of the corresponding field instead. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/lambda/lambda-nested9.C: New test. --- gcc/cp/lambda.c | 19 +++++++-- .../g++.dg/cpp0x/lambda/lambda-nested9.C | 41 +++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 2e9d38bbe83..f16c121dc78 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -196,7 +196,9 @@ lambda_capture_field_type (tree expr, bool explicit_init_p, tree type; bool is_this = is_this_parameter (tree_strip_nop_conversions (expr)); - if (!is_this && explicit_init_p) + if (is_this) + type = TREE_TYPE (expr); + else if (explicit_init_p) { tree auto_node = make_auto (); @@ -210,7 +212,7 @@ lambda_capture_field_type (tree expr, bool explicit_init_p, else type = do_auto_deduction (type, expr, auto_node); } - else if (!is_this && type_dependent_expression_p (expr)) + else if (type_dependent_expression_p (expr)) { type = cxx_make_type (DECLTYPE_TYPE); DECLTYPE_TYPE_EXPR (type) = expr; @@ -220,10 +222,19 @@ lambda_capture_field_type (tree expr, bool explicit_init_p, } else { + if (!by_reference_p && is_capture_proxy (expr)) + { + /* When capturing by-value another capture proxy from an enclosing + lambda, consider the type of the corresponding field instead, + as the proxy may be const-qualifed if the enclosing lambda is + non-mutable (PR94376). */ + gcc_assert (TREE_CODE (DECL_VALUE_EXPR (expr)) == COMPONENT_REF); + expr = TREE_OPERAND (DECL_VALUE_EXPR (expr), 1); + } + type = non_reference (unlowered_expr_type (expr)); - if (!is_this - && (by_reference_p || TREE_CODE (type) == FUNCTION_TYPE)) + if (by_reference_p || TREE_CODE (type) == FUNCTION_TYPE) type = build_reference_type (type); } diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C new file mode 100644 index 00000000000..ff7da3b0ce1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C @@ -0,0 +1,41 @@ +// PR c++/94376 +// { dg-do compile { target c++11 } } + +int main() { + // We used to incorrectly reject the first two cases. + int i = 0; + [=] () { + [=] () mutable { + ++i; + }; + }; + +#if __cpp_init_captures + [j=0] () { + [=] () mutable { + ++j; + }; + }; +#endif + + [=] () { + [&] () mutable { + ++i; // { dg-error "read-only" } + }; + }; + + const int j = 0; + [=] () { + [=] () mutable { + ++j; // { dg-error "read-only" } + }; + }; + +#if __cpp_init_captures + [j=0] () { + [&] () mutable { + ++j; // { dg-error "read-only" } + }; + }; +#endif +}