Bug 79620 - decltype() inside a lambda capturing-by-value
Summary: decltype() inside a lambda capturing-by-value
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.3.1
: P3 normal
Target Milestone: 14.0
Assignee: Patrick Palka
Keywords: c++-lambda, rejects-valid
: 63192 93386 96095 (view as bug list)
Depends on:
Blocks: lambdas
  Show dependency treegraph
Reported: 2017-02-20 03:15 UTC by LIU Hao
Modified: 2023-11-10 16:06 UTC (History)
4 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed: 2017-10-10 00:00:00


Note You need to log in before you can comment on or make changes to this bug.
Description LIU Hao 2017-02-20 03:15:24 UTC
The following example copied from the C++17 draft [N4582] fails to compile:

void f3() {
    float x, &r = x;
    [=] {                       // x and r are not captured (appearance in a decltype operand is not an odr-use)
        decltype(x) y1;         // y1 has type float
        decltype((x)) y2 = y1;  // y2 has type float const& because this lambda
                                // is not mutable and x is an lvalue
        decltype(r) r1 = y1;    // r1 has type float& (transformation not considered)
        decltype((r)) r2 = y2;  // r2 has type float const&

E:\Desktop>g++ -pedantic -pedantic-errors -std=c++14 test.cpp
test.cpp: In lambda function:
test.cpp:8:22: error: binding 'const float' to reference of type 'float&' discards qualifiers
   decltype((r)) r2 = y2;  // r2 has type float const&
Comment 1 Jonathan Wakely 2020-01-22 15:34:32 UTC
*** Bug 93386 has been marked as a duplicate of this bug. ***
Comment 2 Marek Polacek 2020-01-22 18:36:41 UTC
Quoting Jason M.: "looks like more of an issue with how is_lambda_ignored_entity skips captures in unevaluated context."
Comment 3 Andrew Pinski 2021-12-03 09:42:16 UTC
*** Bug 96095 has been marked as a duplicate of this bug. ***
Comment 4 GCC Commits 2023-11-10 15:58:21 UTC
The master branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>:


commit r14-5331-g0410b754e56c0868203c2412e0585ba070ea938d
Author: Patrick Palka <ppalka@redhat.com>
Date:   Fri Nov 10 10:58:06 2023 -0500

    c++: decltype of (by-value captured reference) [PR79620]
    The capture_decltype handling in finish_decltype_type wasn't looking
    through implicit INDIRECT_REF (added by convert_from_reference), which
    caused us to incorrectly resolve decltype((r)) to float& below.  This
    patch fixes this, and adds an assert to outer_automatic_var_p to help
    prevent against such bugs.
    We still don't fully accept the example ultimately because for the
    decltype inside the lambda's trailing return type, at that point we're
    in lambda type scope but not yet in lambda function scope that the
    capture_decltype handling looks for (which is an orthogonal bug).
            PR c++/79620
            * cp-tree.h (STRIP_REFERENCE_REF): Define.
            * semantics.cc (outer_var_p): Assert REFERENCE_REF_P is false.
            (finish_decltype_type): Look through implicit INDIRECT_REF when
            deciding whether to call capture_decltype.
            * g++.dg/cpp0x/lambda/lambda-decltype3.C: New test.
    Reviewed-by: Jason Merrill <jason@redhat.com>
Comment 5 Patrick Palka 2023-11-10 16:00:39 UTC
Fixed for GCC 14.
Comment 6 Patrick Palka 2023-11-10 16:06:20 UTC
*** Bug 63192 has been marked as a duplicate of this bug. ***