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