<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/95992>95992</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [clang] wrong decltype results for a reference captured by value
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          mmatrosov
      </td>
    </tr>
</table>

<pre>
    Consider the following program (https://godbolt.org/z/8EY4G3n68):

```
int main() {
    int i = 0;
    const int& ir = i;
    auto f = [ir] mutable -> const int& { 
        // ir = 13; error
 static_assert(!std::is_const_v<decltype(ir)>);
 static_assert(std::is_reference_v<decltype(ir)>);
        return ir;
 };
    return &ir == &f();
}
```

Here `ir` is a const ref captured by value. It is represented by `const int` member in the closure object (https://eel.is/c++draft/expr.prim.lambda.capture#10):

> For each entity captured by copy, an unnamed non-static data member is declared in the closure type. The type of such a data member is the *referenced type* if the entity is a reference to an object

(I personally see no reason why `const` qualifier should not be stripped off during capture, but this is another story)

The line `ir = 13` does not compile with the error `cannot assign to a variable captured by copy in a non-mutable lambda` which clearly tells that the type is not `int` (and the error is a bit misleading, since the lambda is marked `mutable`). The return code of the program is zero, which tells that the type is not a reference.

However, both `static_asserts` compile, saying `ir` within the closure is a reference, and is non-const. As if they were applied to the outer `ir` in the body of the function.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyMVcFy4zYM_Rr6golGomzZPvgQx3G79156ylAiZLGlSBWk7Hq_vgNKduzstlNNRklEEHx47wFUIZiTQ9yJ1V6sDgs1xs7Tru9VJB_8eVF7fd29eReMRoLYIbTeWn8x7gQD-ROpHoTcdDEOQZSvQh6FPJ68rr2NmaeTkMfvQh43778vfyldtRFyy2H5QeS3d5XPP-lf4yL0yjghORbEej99BwDgNQOiPEAuyofvjXch8qqQFRhKEeYpQo3RQ5sWxGpvSKwO0I9R1RbhRZTvzynEeg-fe_mZ6rrlLkpR7gGJPM1hIapomg8VAlJM0IsQNVdavprwkbJ_nEX5prGx8TqgkBtDiYz39N7_S6LHLIQtEroG_1em-SGMIzkw9Lki1oensDlEyGqqL7Ekq3aS4B7K236m2PT-FQlBVLkhUeVgAqiZU8IWGjXEkVBDfYWzsiNm8C1yEOFAGNDFaU1U-acQVQ499jUSGJec11gfRkLw9R_YxB9th2gzE4Q8NkLuhdxrUm3k738PlA1k-syqvtYqm-EIWRb5TwxZvsPRE6BqOkAXTbw-FdD44SrkGygHo3OqRw3Ou5dJOdAqqjvuAKyS4o1famDlMvitm_4C30IYmw7U1_28R8jXu_QaJs1fwbRpcQaYCL9HQfQMbyLqqTa5-QYDUvBOWXuFgAjOA6EK3sGl-5SA6f9rVNa0BglC50fLdUaoEUIkMwyowbct6JF4GNw5fYN6jBA7ExIo52PHCaKnK3P9AIart8bNtrl1VpWD9hjSWY3vB2MRLiZ2U7Xccwmjchwwza9ULpwVmdTQX8Vi7lXS6Nbykw_4qEtnmg4ai4rsFSJay5yrmE5L0pgJCmOcTCnkRjn9ACdxX5sIvQkWlTbuxDQEk5TobsdxXK_oT9ScbIbCXSS3kxPmPmy8TobgnbcRawJ8R_KcdkL8H0gffJA9dai_4BkpKeRjxyCepk3g4mbGE351ZWHvPc0ifHHxs-umptATDveSbJTBa5iteoULzwg1DNawj31K5ceI9DA4pgP42rlx0I6uica7bKF3pd6WW7XAXbEuNuvlKs_Xi25X5ljJoijyddtU1XJdN8taqa1sWl2oclUtzE7mcplXxUYWRZ6vM1Ryu2m2qLebom1Ri2WOvTI2s_bc8721MCGMuNuutlu5sKpGG9IdKWVjFesr-bqkHce_1OMpiGVuTYjhM0M00aaLddqxOsCFvDvBbXADYRhtDNB6emreH6blYiS7-3LFmtiNddb4XsgjHzn_ehnIp6aXx1QBj8OpiPNO_hMAAP__OJKGqg">