From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 4B73C385E009; Sat, 28 Mar 2020 00:14:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4B73C385E009 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1585354460; bh=9O7TOvTASH/iYkeXazJB/UE0HTE9SXTk0+GVSYuvUZ0=; h=From:To:Subject:Date:From; b=MNGaubElarzjcA4f3QOQ9F5kKDZJKNj7qKKFKAZukSArKmU3O5NvhXFieegLNtVw8 5kLIbgeYeWE6h9RXL+jqOrOdtekaqTl9HLmK71mje0AeWlhMFoM14ZDlqrC2YfFx5S 2uGGwZ7O56HAKcm2M61YCRKTcFnbYeJrHuuQjwSM= From: "arthur.j.odwyer at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/94376] New: When nested inside a lambda body, [=] captures by const value instead of by value Date: Sat, 28 Mar 2020 00:14:20 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: unknown X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: arthur.j.odwyer at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Mar 2020 00:14:20 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D94376 Bug ID: 94376 Summary: When nested inside a lambda body, [=3D] captures by const value instead of by value Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: arthur.j.odwyer at gmail dot com Target Milestone: --- David Blaikie, Richard Smith, and I discovered this GCC bug while tracking = down a separate bug in llvm::function_ref whose constructor template was imprope= rly SFINAEd so that construction from `const T&&` was done wrong. A GCC bug cau= sed construction from `const T&&` to happen on GCC but not on Clang or EDG. Her= e's the reduced test case: // https://godbolt.org/z/oCvLpv #include #include struct I { I() { puts(__PRETTY_FUNCTION__); } I(I&) { puts(__PRETTY_FUNCTION__); } I(const I&) { puts(__PRETTY_FUNCTION__); } I(I&&) { puts(__PRETTY_FUNCTION__); } I(const I&&) { puts(__PRETTY_FUNCTION__); } void operator++() const {} }; int main() { I i; auto one =3D [=3D]() {=20 return [=3D]() { ++i; }; }(); puts("-----"); auto two =3D std::move(one); // !! } On the line marked "!!", one's implicitly generated move-constructor calls `I(const I&&)` rather than `I(I&&)` to move the captured copy of `i`. It do= es this because it has improperly decided that the type of the captured copy of `i` should be `const I` instead of plain old `I`. Richard Smith writes: > [expr.prim.lambda.capture]p10 is the relevant rule: > "The type of such a data member is the referenced type > if the entity is a reference to an object, an lvalue reference > to the referenced function type if the entity is a reference to a functio= n, > or the type of the corresponding captured entity otherwise." > > Regardless of whether you think the captured entity is > the original variable or the member of the outer closure type, > the type of that entity is not const-qualified. > So the inner capture should not have a const-qualified type. Besides exposing bugs in llvm::function_ref (a good effect!), GCC's implementation divergence here could have the bad effect of causing additio= nal expensive copies when lambdas with improperly const-qualified captures are moved around. Example: https://godbolt.org/z/LWEF47 Bug 86697 might be related: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D86697=