1 // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow -D AVOID %s
2 // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow -Wshadow-uncaptured-local %s
3 // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow-all %s
4 // RUN: %clang_cc1 -std=c++17 -verify -fsyntax-only -Wshadow-all %s
5 
foo(int param)6 void foo(int param) { // expected-note 1+ {{previous declaration is here}}
7   int var = 0; // expected-note 1+ {{previous declaration is here}}
8 
9   // Avoid warnings for variables that aren't implicitly captured.
10   {
11 #ifdef AVOID
12     auto f1 = [=] { int var = 1; };  // no warning
13     auto f2 = [&] { int var = 2; };  // no warning
14     auto f3 = [=] (int param) { ; }; // no warning
15     auto f4 = [&] (int param) { ; }; // no warning
16 #else
17     auto f1 = [=] { int var = 1; };  // expected-warning {{declaration shadows a local variable}}
18     auto f2 = [&] { int var = 2; };  // expected-warning {{declaration shadows a local variable}}
19     auto f3 = [=] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
20     auto f4 = [&] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
21 #endif
22   }
23 
24   // Warn for variables that are implicitly captured.
25   {
26     auto f1 = [=] () {
27       {
28         int var = 1; // expected-warning {{declaration shadows a local variable}}
29       }
30       int x = var; // expected-note {{variable 'var' is captured here}}
31     };
32     auto f2 = [&]
33 #ifdef AVOID
34       (int param) {
35 #else
36       (int param) { // expected-warning {{declaration shadows a local variable}}
37 #endif
38       int x = var; // expected-note {{variable 'var' is captured here}}
39       int var = param; // expected-warning {{declaration shadows a local variable}}
40     };
41   }
42 
43   // Warn for variables that are explicitly captured when a lambda has a default
44   // capture specifier.
45   {
46     auto f1 = [=, &var] () { // expected-note {{variable 'var' is captured here}}
47       int x = param; // expected-note {{variable 'param' is captured here}}
48       int var = 0; // expected-warning {{declaration shadows a local variable}}
49       int param = 0; // expected-warning {{declaration shadows a local variable}}
50     };
51   }
52 
53   // Warn normally inside of lambdas.
54   auto l1 = [] { // expected-note {{previous declaration is here}}
55       int x = 1; // expected-note {{previous declaration is here}}
56       { int x = 2; } // expected-warning {{declaration shadows a local variable}}
57   };
58   auto l2 = [] (int x) { // expected-note {{previous declaration is here}}
59     { int x = 1; } // expected-warning {{declaration shadows a local variable}}
60   };
61 
62   // Avoid warnings for variables that aren't explicitly captured.
63   {
64 #ifdef AVOID
65     auto f1 = [] { int var = 1; }; // no warning
66     auto f2 = [] (int param) { ; }; // no warning
67     auto f3 = [param] () { int var = 1; }; // no warning
68     auto f4 = [var] (int param) { ; }; // no warning
69 #else
70     auto f1 = [] { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
71     auto f2 = [] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
72     auto f3 = [param] () { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
73     auto f4 = [var] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
74 #endif
75   };
76 
77   // Warn for variables that are explicitly captured.
78   {
79     auto f1 = [var] () { // expected-note {{variable 'var' is explicitly captured here}}
80       int var = 1; // expected-warning {{declaration shadows a local variable}}
81     };
82     auto f2 = [param]   // expected-note {{variable 'param' is explicitly captured here}}
83      (int param) { ; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}}
84   }
85 
86   // Warn for variables defined in the capture list.
87   auto l3 = [z = var] { // expected-note {{previous declaration is here}}
88 #ifdef AVOID
89     int var = 1; // no warning
90 #else
91     int var = 1; // expected-warning {{declaration shadows a local variable}}
92 #endif
93     { int z = 1; } // expected-warning {{declaration shadows a local variable}}
94   };
95 #ifdef AVOID
96   auto l4 = [var = param] (int param) { ; }; // no warning
97 #else
98   auto l4 = [var = param] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
99 #endif
100 
101   // Make sure that inner lambdas work as well.
102   auto l5 = [var, l1] { // expected-note {{variable 'l1' is explicitly captured here}}
103     auto l1 = [] { // expected-warning {{declaration shadows a local variable}}
104 #ifdef AVOID
105       int var = 1; // no warning
106 #else
107       int var = 1; // expected-warning {{declaration shadows a local variable}}
108 #endif
109     };
110 #ifdef AVOID
111     auto f1 = [] { int var = 1; }; // no warning
112     auto f2 = [=] { int var = 1; }; // no warning
113 #else
114     auto f1 = [] { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
115     auto f2 = [=] { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
116 #endif
117     auto f3 = [var] // expected-note {{variable 'var' is explicitly captured here}}
118       { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
119     auto f4 = [&] {
120       int x = var; // expected-note {{variable 'var' is captured here}}
121       int var = 2; // expected-warning {{declaration shadows a local variable}}
122     };
123   };
124   auto l6 = [&] {
125     auto f1 = [param] { // expected-note {{variable 'param' is explicitly captured here}}
126       int param = 0; // expected-warning {{declaration shadows a local variable}}
127     };
128   };
129 
130   // Generic lambda arguments should work.
131 #ifdef AVOID
132   auto g1 = [](auto param) { ; }; // no warning
133   auto g2 = [=](auto param) { ; }; // no warning
134 #else
135   auto g1 = [](auto param) { ; }; // expected-warning {{declaration shadows a local variable}}
136   auto g2 = [=](auto param) { ; }; // expected-warning {{declaration shadows a local variable}}
137 #endif
138   auto g3 = [param] // expected-note {{variable 'param' is explicitly captured here}}
139    (auto param) { ; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}}
140 }
141 
142 void avoidWarningWhenRedefining() {
143   int a = 1;
144   auto l = [b = a] { // expected-note {{previous definition is here}}
145     // Don't warn on redefinitions.
146     int b = 0; // expected-error {{redefinition of 'b'}}
147   };
148 }
149