Created attachment 40647 [details] example -Wshadow warnings have a confusing interaction with lambda captures. 1) The names of init lambda captures are not checked. 2) local names are checked regardless of whether there is a default capture to make an outer object accessible The original report also mentioned the following case: T x; [=, x = std::move(x)] {}; if T is a non-copyable type, the default = capture couldn't capture it. IMHO such nuance shouldn't affect whether or not this gives a warning (so it should warn). I think it clear that #1 should be checked, but I can see arguments for and against #2. I think of name hiding as (almost) a syntactic check, and whether an object can be captured is more of a semantic check.
If I may, I think at least this case // Warning considered erroneous // There is no default capture to get at the outer object void haveWarningBad (int x) { [] { int x; }; } should be fixed not to produce any warnings.
Created attachment 46658 [details] simple test case Build with g++-9 test.cc -Wshadow -o test
This defect makes -Wshadow=local difficult to use with immediately invoked lambda expressions. For instance, gcc 9.2 compiles: #include <array> auto f(int s) { const auto v = []{ std::array<int,2> v = {1, 2}; return v; }(); return v.size(); } with: source>: In lambda function: <source>:4:25: warning: declaration of 'v' shadows a previous local [-Wshadow] 4 | std::array<int,2> v = {1, 2}; | ^ <source>:3:14: note: shadowed declaration is here 3 | const auto v = []{ | ^
Can confirm this also happens with gcc 10.2.0.
still in 13.3
Still not fixed in 15.2. https://godbolt.org/z/zeed4KhM1