[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCXX / warn-shadow-in-lambdas.cpp
blobd54b394df4eb849d44013f0329dbdddbbef1e458
1 // RUN: %clang_cc1 -std=c++14 -verify=expected,cxx14 -fsyntax-only -Wshadow -D AVOID %s
2 // RUN: %clang_cc1 -std=c++14 -verify=expected,cxx14 -fsyntax-only -Wshadow -Wshadow-uncaptured-local %s
3 // RUN: %clang_cc1 -std=c++14 -verify=expected,cxx14 -fsyntax-only -Wshadow-all %s
4 // RUN: %clang_cc1 -std=c++17 -verify -fsyntax-only -Wshadow-all %s
5 // RUN: %clang_cc1 -std=c++20 -verify -fsyntax-only -Wshadow-all %s
7 void foo(int param) { // expected-note 1+ {{previous declaration is here}}
8 int var = 0; // expected-note 1+ {{previous declaration is here}}
10 // Avoid warnings for variables that aren't implicitly captured.
12 #ifdef AVOID
13 auto f1 = [=] { int var = 1; }; // no warning
14 auto f2 = [&] { int var = 2; }; // no warning
15 auto f3 = [=] (int param) { ; }; // no warning
16 auto f4 = [&] (int param) { ; }; // no warning
17 auto f5 = [=] { static int var = 1; }; // no warning
18 auto f6 = [&] { static int var = 2; }; // no warning
19 #else
20 auto f1 = [=] { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
21 auto f2 = [&] { int var = 2; }; // expected-warning {{declaration shadows a local variable}}
22 auto f3 = [=] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
23 auto f4 = [&] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
24 auto f5 = [=] { static int var = 1; }; // expected-warning {{declaration shadows a local variable}}
25 auto f6 = [&] { static int var = 2; }; // expected-warning {{declaration shadows a local variable}}
26 #endif
29 // Warn for variables that are implicitly captured.
31 auto f1 = [=] () {
33 int var = 1; // expected-warning {{declaration shadows a local variable}}
35 int x = var; // expected-note {{variable 'var' is captured here}}
37 auto f2 = [&]
38 #ifdef AVOID
39 (int param) {
40 #else
41 (int param) { // expected-warning {{declaration shadows a local variable}}
42 #endif
43 int x = var; // expected-note {{variable 'var' is captured here}}
44 int var = param; // expected-warning {{declaration shadows a local variable}}
48 // Warn for variables that are explicitly captured when a lambda has a default
49 // capture specifier.
51 auto f1 = [=, &var] () { // expected-note {{variable 'var' is captured here}}
52 int x = param; // expected-note {{variable 'param' is captured here}}
53 int var = 0; // expected-warning {{declaration shadows a local variable}}
54 int param = 0; // expected-warning {{declaration shadows a local variable}}
58 // Warn normally inside of lambdas.
59 auto l1 = [] { // expected-note {{previous declaration is here}}
60 int x = 1; // expected-note {{previous declaration is here}}
61 { int x = 2; } // expected-warning {{declaration shadows a local variable}}
63 auto l2 = [] (int x) { // expected-note {{previous declaration is here}}
64 { int x = 1; } // expected-warning {{declaration shadows a local variable}}
67 // Avoid warnings for variables that aren't explicitly captured.
69 #ifdef AVOID
70 auto f1 = [] { int var = 1; }; // no warning
71 auto f2 = [] (int param) { ; }; // no warning
72 auto f3 = [param] () { int var = 1; }; // no warning
73 auto f4 = [var] (int param) { ; }; // no warning
74 auto f5 = [param] () { static int var = 1; }; // no warning
75 auto f6 = [] { static int var = 1; }; // no warning
76 #else
77 auto f1 = [] { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
78 auto f2 = [] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
79 auto f3 = [param] () { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
80 auto f4 = [var] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
81 auto f5 = [param] () { static int var = 1; }; // expected-warning {{declaration shadows a local variable}}
82 auto f6 = [] { static int var = 1; }; // expected-warning {{declaration shadows a local variable}}
83 #endif
86 // Warn for variables that are explicitly captured.
88 auto f1 = [var] () { // expected-note {{variable 'var' is explicitly captured here}}
89 int var = 1; // expected-warning {{declaration shadows a local variable}}
91 auto f2 = [param] // expected-note {{variable 'param' is explicitly captured here}}
92 (int param) { ; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}}
95 // Warn for variables defined in the capture list.
96 auto l3 = [z = var] { // expected-note {{previous declaration is here}}
97 #ifdef AVOID
98 int var = 1; // no warning
99 #else
100 int var = 1; // expected-warning {{declaration shadows a local variable}}
101 #endif
102 { int z = 1; } // expected-warning {{declaration shadows a local variable}}
104 #ifdef AVOID
105 auto l4 = [var = param] (int param) { ; }; // no warning
106 #else
107 auto l4 = [var = param](int param) { ; }; // expected-warning 2{{declaration shadows a local variable}}
108 #endif
110 // Make sure that inner lambdas work as well.
111 auto l5 = [var, l1] { // expected-note {{variable 'l1' is explicitly captured here}}
112 auto l1 = [] { // expected-warning {{declaration shadows a local variable}}
113 #ifdef AVOID
114 int var = 1; // no warning
115 #else
116 int var = 1; // expected-warning {{declaration shadows a local variable}}
117 #endif
119 #ifdef AVOID
120 auto f1 = [] { int var = 1; }; // no warning
121 auto f2 = [=] { int var = 1; }; // no warning
122 #else
123 auto f1 = [] { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
124 auto f2 = [=] { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
125 #endif
126 auto f3 = [var] // expected-note {{variable 'var' is explicitly captured here}}
127 { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
128 auto f4 = [&] {
129 int x = var; // expected-note {{variable 'var' is captured here}}
130 int var = 2; // expected-warning {{declaration shadows a local variable}}
133 auto l6 = [&] {
134 auto f1 = [param] { // expected-note {{variable 'param' is explicitly captured here}}
135 int param = 0; // expected-warning {{declaration shadows a local variable}}
138 auto l7 = [&] {
139 auto f1 = [param] { // expected-note {{variable 'param' is explicitly captured here}}
140 static int param = 0; // expected-warning {{declaration shadows a local variable}}
144 // Generic lambda arguments should work.
145 #ifdef AVOID
146 auto g1 = [](auto param) { ; }; // no warning
147 auto g2 = [=](auto param) { ; }; // no warning
148 #else
149 auto g1 = [](auto param) { ; }; // expected-warning {{declaration shadows a local variable}}
150 auto g2 = [=](auto param) { ; }; // expected-warning {{declaration shadows a local variable}}
151 #endif
152 auto g3 = [param] // expected-note {{variable 'param' is explicitly captured here}}
153 (auto param) { ; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}}
156 void avoidWarningWhenRedefining() {
157 int a = 1;
158 auto l = [b = a] { // expected-note {{previous definition is here}}
159 // Don't warn on redefinitions.
160 int b = 0; // expected-error {{redefinition of 'b'}}
164 namespace GH61105 {
165 void f() {
166 int y = 0;
167 int x = 0;
168 #if __cplusplus >= 202002L
169 auto l1 = [y]<typename y>(y) { return 0; }; // expected-error {{declaration of 'y' shadows template parameter}} \
170 // expected-note {{template parameter is declared here}}
171 auto l2 = [=]<typename y>() { int a = y; return 0; }; // expected-error {{'y' does not refer to a value}} \
172 // expected-note {{declared here}}
173 auto l3 = [&, y]<typename y, typename>(y) { int a = x; return 0; }; // expected-error {{declaration of 'y' shadows template parameter}} \
174 // expected-note {{template parameter is declared here}}
175 auto l4 = [x, y]<typename y, int x>() { return 0; }; // expected-error {{declaration of 'y' shadows template parameter}} \
176 // expected-error {{declaration of 'x' shadows template parameter}} \
177 // expected-note 2{{template parameter is declared here}}
178 auto l5 = []<typename y>(y) { return 0; }; // No diagnostic
179 #endif
183 namespace GH71976 {
184 #ifdef AVOID
185 struct A {
186 int b = 5;
187 int foo() {
188 return [b = b]() { return b; }(); // no -Wshadow diagnostic, init-capture does not shadow b due to not capturing this
192 struct B {
193 int a;
194 void foo() {
195 auto b = [a = this->a] {}; // no -Wshadow diagnostic, init-capture does not shadow a due to not capturing his
199 struct C {
200 int b = 5;
201 int foo() {
202 return [a = b]() {
203 return [=, b = a]() { // no -Wshadow diagnostic, init-capture does not shadow b due to outer lambda
204 return b;
205 }();
206 }();
210 #else
211 struct A {
212 int b = 5; // expected-note {{previous}}
213 int foo() {
214 return [b = b]() { return b; }(); // expected-warning {{declaration shadows a field}}
218 struct B {
219 int a; // expected-note {{previous}}
220 void foo() {
221 auto b = [a = this->a] {}; // expected-warning {{declaration shadows a field}}
225 struct C {
226 int b = 5; // expected-note {{previous}}
227 int foo() {
228 return [a = b]() {
229 return [=, b = a]() { // expected-warning {{declaration shadows a field}}
230 return b;
231 }();
232 }();
236 struct D {
237 int b = 5; // expected-note {{previous}}
238 int foo() {
239 return [b = b, this]() { return b; }(); // expected-warning {{declaration shadows a field}}
243 struct E {
244 int b = 5;
245 int foo() {
246 return [a = b]() { // expected-note {{previous}}
247 return [=, a = a]() { // expected-warning {{shadows a local}}
248 return a;
249 }();
250 }();
254 #endif
256 struct S {
257 int a ;
260 int foo() {
261 auto [a] = S{0}; // expected-note {{previous}} \
262 // cxx14-warning {{decomposition declarations are a C++17 extension}}
263 [a = a] () { // expected-warning {{declaration shadows a structured binding}}
264 }();