Bug 95368 - gcc things that a lambda capture is both const and mutable
Summary: gcc things that a lambda capture is both const and mutable
Status: RESOLVED DUPLICATE of bug 94376
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 10.1.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: c++-lambda, needs-bisection, rejects-valid
Depends on:
Blocks: lambdas
  Show dependency treegraph
 
Reported: 2020-05-27 15:24 UTC by Rafael Avila de Espindola
Modified: 2022-03-11 00:32 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work: 12.0
Known to fail: 11.1.0
Last reconfirmed: 2021-12-28 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rafael Avila de Espindola 2020-05-27 15:24:00 UTC
gcc accepts

#include <utility>

struct foo {
    void func();
};

void bar(foo& v) {
    [v]() {
        static_assert(std::is_same_v<decltype(v), foo&>);
        [v]() mutable {
            static_assert(std::is_same_v<decltype(v), foo&>);
//            v.func();                                                                                                                                                                                
        }();
    }();
}


But uncomment the call and you get

test.cc:12:20: error: passing ‘const foo’ as ‘this’ argument discards qualifiers [-fpermissive]
   12 |             v.func();
Comment 1 Daniel Krügler 2020-05-27 16:35:56 UTC
(In reply to Rafael Avila de Espindola from comment #0)
> gcc accepts
> 
[..]

I found your code confusing, because the actual problem becomes visible only under certain conditions. So lets make it a proper example, that shows the problem immediately and lets ensure that we make it free from library dependencies and provide all required information:

When using 

gcc HEAD 11.0.0 20200525 (experimental) 

and the following compiler flags

-Wall -Wextra -std=gnu++2a -pedantic 

to compile this code:

//---------
template<class, class>
constexpr bool is_same_v = false;

template<class T>
constexpr bool is_same_v<T, T> = true;

struct foo
{
  void func() {}
};

void bar(foo& v) {
  [v]() {
    static_assert(is_same_v<decltype(v), foo&>);
    [v]() mutable {
      static_assert(is_same_v<decltype(v), foo&>);
      v.func();
    }();
  }();
}

int main() {}
//---------

the program is rejected (but should be accepted) with the following diagnostics:

```
prog.cc: In lambda function:
prog.cc:17:16: error: passing 'const foo' as 'this' argument discards qualifiers [-fpermissive]
   17 |         v.func();
      |                ^
prog.cc:9:8: note:   in call to 'void foo::func()'
    9 |   void func() {}
      |        ^~~~
```
Comment 2 Rafael Avila de Espindola 2020-05-28 17:00:34 UTC
I just tested a few compilers with the testcase from comment 1:

* clang version 11.0.0 (https://github.com/llvm/llvm-project.git 0796b170fb3bf38e6cc4e59746120b37c9a9cd9f):
  Accepts it.

* g++ (GCC) 10.1.1 20200507 (Red Hat 10.1.1-1):
  Rejects it:
  test.cc:17:14: error: passing ‘const foo’ as ‘this’ argument discards qualifiers [-fpermissive]

* gcc (GCC) 9.3.1 20200528
  Rejects it:
  test.cc:17:14: error: passing ‘const foo’ as ‘this’ argument discards qualifiers
Comment 3 Andrew Pinski 2021-12-28 09:55:56 UTC
Looks to be fixed on the trunk.
Comment 4 Andrew Pinski 2021-12-28 10:01:24 UTC
Dup of bug 94376

*** This bug has been marked as a duplicate of bug 94376 ***