Bug 79328

Summary: Wshadow and lambda captures
Product: gcc Reporter: Nathan Sidwell <nathan>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: UNCONFIRMED ---    
Severity: enhancement CC: arnaud02, eb, egallager, lvella, mika.fischer, paul.skeptic, sjames, webrown.cpp
Priority: P3 Keywords: c++-lambda, diagnostic
Version: 7.0   
Target Milestone: ---   
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112309
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121553
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:
Bug Depends on:    
Bug Blocks: 105828, 54367    
Attachments: example
simple test case

Description Nathan Sidwell 2017-02-01 16:52:56 UTC
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.
Comment 1 Andrea Bocci 2019-08-02 08:18:03 UTC
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.
Comment 2 Andrea Bocci 2019-08-02 08:18:58 UTC
Created attachment 46658 [details]
simple test case

Build with

g++-9 test.cc -Wshadow -o test
Comment 3 Arnaud Desitter 2019-09-27 15:13:25 UTC
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 = []{

      |              ^
Comment 4 Lucas Clemente Vella 2021-05-27 17:57:17 UTC
Can confirm this also happens with gcc 10.2.0.
Comment 5 Rolf Eike Beer 2024-08-15 07:16:31 UTC
still in 13.3
Comment 6 Pavel Novikov 2025-09-21 13:20:44 UTC
Still not fixed in 15.2.
https://godbolt.org/z/zeed4KhM1