Clang Project

clang_source_code/test/SemaCXX/warn-unused-lambda-capture.cpp
1// RUN: %clang_cc1 -fsyntax-only -Wunused-lambda-capture -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++1z %s
2
3class NonTrivialConstructor {
4public:
5  NonTrivialConstructor() {}
6};
7
8class NonTrivialCopyConstructor {
9public:
10  NonTrivialCopyConstructor() = default;
11  NonTrivialCopyConstructor(const NonTrivialCopyConstructor &) {}
12};
13
14class NonTrivialDestructor {
15public:
16  ~NonTrivialDestructor() {}
17};
18
19class Trivial {
20public:
21  Trivial() = default;
22  Trivial(int a) {}
23};
24
25int side_effect() {
26  return 42;
27}
28
29void test() {
30  int i = 0;
31  const int k = 0;
32
33  auto captures_nothing = [] {};
34
35  auto captures_nothing_by_value = [=] {};
36  auto captures_nothing_by_reference = [&] {};
37
38  auto implicit_by_value = [=]() mutable { i++; };
39  auto implicit_by_reference = [&] { i++; };
40
41  auto explicit_by_value_used = [i] { return i + 1; };
42  auto explicit_by_value_used_void = [i] { (void)i; };
43  auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
44  auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
45  auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
46  auto explicit_by_value_unused_const = [k] { return k + 1; };         // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
47
48  auto explicit_by_reference_used = [&i] { i++; };
49  auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}}
50
51  auto explicit_initialized_reference_used = [&j = i] { return j + 1; };
52  auto explicit_initialized_reference_unused = [&j = i]{}; // expected-warning{{lambda capture 'j' is not used}}
53
54  auto explicit_initialized_value_used = [j = 1] { return j + 1; };
55  auto explicit_initialized_value_unused = [j = 1] {}; // expected-warning{{lambda capture 'j' is not used}}
56  auto explicit_initialized_value_non_trivial_constructor = [j = NonTrivialConstructor()]{};
57  auto explicit_initialized_value_non_trivial_destructor = [j = NonTrivialDestructor()]{};
58  auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}}
59  auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{};
60  auto explicit_initialized_value_with_side_effect = [j = side_effect()]{};
61
62  auto nested = [&i] {
63    auto explicit_by_value_used = [i] { return i + 1; };
64    auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
65  };
66
67  Trivial trivial;
68  auto explicit_by_value_trivial = [trivial] {}; // expected-warning{{lambda capture 'trivial' is not used}}
69
70  NonTrivialConstructor cons;
71  auto explicit_by_value_non_trivial_constructor = [cons] {}; // expected-warning{{lambda capture 'cons' is not used}}
72
73  NonTrivialCopyConstructor copy_cons;
74  auto explicit_by_value_non_trivial_copy_constructor = [copy_cons] {};
75
76  NonTrivialDestructor dest;
77  auto explicit_by_value_non_trivial_destructor = [dest] {};
78
79  volatile int v;
80  auto explicit_by_value_volatile = [v] {};
81}
82
83class TrivialThis : Trivial {
84  void test() {
85    auto explicit_this_used = [this] { return i; };
86    auto explicit_this_used_void = [this] { (void)this; };
87    auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
88    auto explicit_star_this_used = [*this] { return i; };
89    auto explicit_star_this_used_void = [*this] { (void)this; };
90    auto explicit_star_this_unused = [*this] {}; // expected-warning{{lambda capture 'this' is not used}}
91  }
92  int i;
93};
94
95class NonTrivialConstructorThis : NonTrivialConstructor {
96  void test() {
97    auto explicit_this_used = [this] { return i; };
98    auto explicit_this_used_void = [this] { (void)this; };
99    auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
100    auto explicit_star_this_used = [*this] { return i; };
101    auto explicit_star_this_used_void = [*this] { (void)this; };
102    auto explicit_star_this_unused = [*this] {}; // expected-warning{{lambda capture 'this' is not used}}
103  }
104  int i;
105};
106
107class NonTrivialCopyConstructorThis : NonTrivialCopyConstructor {
108  void test() {
109    auto explicit_this_used = [this] { return i; };
110    auto explicit_this_used_void = [this] { (void)this; };
111    auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
112    auto explicit_star_this_used = [*this] { return i; };
113    auto explicit_star_this_used_void = [*this] { (void)this; };
114    auto explicit_star_this_unused = [*this] {};
115  }
116  int i;
117};
118
119class NonTrivialDestructorThis : NonTrivialDestructor {
120  void test() {
121    auto explicit_this_used = [this] { return i; };
122    auto explicit_this_used_void = [this] { (void)this; };
123    auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
124    auto explicit_star_this_used = [*this] { return i; };
125    auto explicit_star_this_used_void = [*this] { (void)this; };
126    auto explicit_star_this_unused = [*this] {};
127  }
128  int i;
129};
130
131template <typename T>
132void test_templated() {
133  int i = 0;
134  const int k = 0;
135
136  auto captures_nothing = [] {};
137
138  auto captures_nothing_by_value = [=] {};
139  auto captures_nothing_by_reference = [&] {};
140
141  auto implicit_by_value = [=]() mutable { i++; };
142  auto implicit_by_reference = [&] { i++; };
143
144  auto explicit_by_value_used = [i] { return i + 1; };
145  auto explicit_by_value_used_generic = [i](auto c) { return i + 1; };
146  auto explicit_by_value_used_void = [i] { (void)i; };
147
148  auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
149  auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
150  auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}}
151  auto explicit_by_value_unused_const = [k] { return k + 1; };         // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
152  auto explicit_by_value_unused_const_generic = [k](auto c) { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
153
154  auto explicit_by_reference_used = [&i] { i++; };
155  auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}}
156
157  auto explicit_initialized_reference_used = [&j = i] { return j + 1; };
158  auto explicit_initialized_reference_unused = [&j = i]{}; // expected-warning{{lambda capture 'j' is not used}}
159
160  auto explicit_initialized_value_used = [j = 1] { return j + 1; };
161  auto explicit_initialized_value_unused = [j = 1] {}; // expected-warning{{lambda capture 'j' is not used}}
162  auto explicit_initialized_value_non_trivial_constructor = [j = NonTrivialConstructor()]{};
163  auto explicit_initialized_value_non_trivial_destructor = [j = NonTrivialDestructor()]{};
164  auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}}
165  auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{};
166  auto explicit_initialized_value_with_side_effect = [j = side_effect()]{};
167  auto explicit_initialized_value_generic_used = [i = 1](auto c) mutable { i++; };
168  auto explicit_initialized_value_generic_unused = [i = 1](auto c) mutable {}; // expected-warning{{lambda capture 'i' is not used}}
169
170  auto nested = [&i] {
171    auto explicit_by_value_used = [i] { return i + 1; };
172    auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
173  };
174
175  Trivial trivial;
176  auto explicit_by_value_trivial = [trivial] {}; // expected-warning{{lambda capture 'trivial' is not used}}
177
178  NonTrivialConstructor cons;
179  auto explicit_by_value_non_trivial_constructor = [cons] {}; // expected-warning{{lambda capture 'cons' is not used}}
180
181  NonTrivialCopyConstructor copy_cons;
182  auto explicit_by_value_non_trivial_copy_constructor = [copy_cons] {};
183
184  NonTrivialDestructor dest;
185  auto explicit_by_value_non_trivial_destructor = [dest] {};
186
187  volatile int v;
188  auto explicit_by_value_volatile = [v] {};
189}
190
191void test_use_template() {
192  test_templated<int>(); // expected-note{{in instantiation of function template specialization 'test_templated<int>' requested here}}
193}
194
195namespace pr35555 {
196int a;
197void b() {
198  int c[a];
199  auto vla_used = [&c] { return c[0]; };
200  auto vla_unused = [&c] {}; // expected-warning{{lambda capture 'c' is not used}}
201}
202} // namespace pr35555
203