[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCXX / warn-unused-variables.cpp
blob216873aa4074b5f3147d1b90981704bc4ad317a6
1 // RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify=expected,cxx98-14 -std=gnu++11 %s
3 // RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify=expected,cxx98-14 -std=gnu++14 %s
4 // RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify -std=gnu++17 %s
6 // RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify %s -fexperimental-new-constant-interpreter
7 // RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify=expected,cxx98-14 -std=gnu++11 %s -fexperimental-new-constant-interpreter
8 // RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify=expected,cxx98-14 -std=gnu++14 %s -fexperimental-new-constant-interpreter
9 // RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify -std=gnu++17 %s -fexperimental-new-constant-interpreter
11 template<typename T> void f() {
12 T t;
13 t = 17;
16 // PR5407
17 struct A { A(); };
18 struct B { ~B(); };
19 void f() {
20 A a;
21 B b;
24 // PR5531
25 namespace PR5531 {
26 struct A {
29 struct B {
30 B(int);
33 struct C {
34 ~C();
37 void test() {
38 A();
39 B(17);
40 C();
44 template<typename T>
45 struct X0 { };
47 template<typename T>
48 void test_dependent_init(T *p) {
49 X0<int> i(p);
50 (void)i;
53 void unused_local_static() {
54 static int x = 0;
55 static int y = 0; // expected-warning{{unused variable 'y'}}
56 #pragma unused(x)
57 static __attribute__((used)) int z;
58 static __attribute__((unused)) int w;
59 [[maybe_unused]] static int v;
62 // PR10168
63 namespace PR10168 {
64 // We expect a warning in the definition only for non-dependent variables, and
65 // a warning in the instantiation only for dependent variables.
66 template<typename T>
67 struct S {
68 void f() {
69 int a; // expected-warning {{unused variable 'a'}}
70 T b; // expected-warning 2{{unused variable 'b'}}
74 template<typename T>
75 void f() {
76 int a; // expected-warning {{unused variable 'a'}}
77 T b; // expected-warning 2{{unused variable 'b'}}
80 void g() {
81 S<int>().f(); // expected-note {{here}}
82 S<char>().f(); // expected-note {{here}}
83 f<int>(); // expected-note {{here}}
84 f<char>(); // expected-note {{here}}
88 namespace PR11550 {
89 struct S1 {
90 S1();
92 S1 makeS1();
93 void testS1(S1 a) {
94 // This constructor call can be elided.
95 S1 x = makeS1(); // expected-warning {{unused variable 'x'}}
97 // This one cannot, so no warning.
98 S1 y;
100 // This call cannot, but the constructor is trivial.
101 S1 z = a; // expected-warning {{unused variable 'z'}}
104 // The same is true even when we know thet constructor has side effects.
105 void foo();
106 struct S2 {
107 S2() {
108 foo();
111 S2 makeS2();
112 void testS2(S2 a) {
113 S2 x = makeS2(); // expected-warning {{unused variable 'x'}}
114 S2 y;
115 S2 z = a; // expected-warning {{unused variable 'z'}}
118 // Or when the constructor is not declared by the user.
119 struct S3 {
120 S1 m;
122 S3 makeS3();
123 void testS3(S3 a) {
124 S3 x = makeS3(); // expected-warning {{unused variable 'x'}}
125 S3 y;
126 S3 z = a; // expected-warning {{unused variable 'z'}}
130 namespace PR19305 {
131 template<typename T> int n = 0; // no warning
132 int a = n<int>;
134 template<typename T> const int l = 0; // no warning
135 int b = l<int>;
137 // PR19558
138 template<typename T> const int o = 0; // no warning
139 template<typename T> const int o<T*> = 0; // no warning
140 int c = o<int*>;
142 template<> int o<void> = 0; // no warning
143 int d = o<void>;
145 // FIXME: It'd be nice to warn here.
146 template<typename T> int m = 0;
147 template<typename T> int m<T*> = 0;
149 // This has external linkage, so could be referenced by a declaration in a
150 // different translation unit.
151 template<> const int m<void> = 0; // no warning
154 namespace ctor_with_cleanups {
155 struct S1 {
156 ~S1();
158 struct S2 {
159 S2(const S1&);
161 void func() {
162 S2 s((S1()));
166 #include "Inputs/warn-unused-variables.h"
168 class NonTriviallyDestructible {
169 public:
170 ~NonTriviallyDestructible() {}
173 namespace arrayRecords {
175 struct Foo {
176 int x;
177 Foo(int x) : x(x) {}
180 struct Elidable {
181 Elidable();
184 void foo(int size) {
185 Elidable elidable; // no warning
186 Elidable elidableArray[2]; // no warning
187 Elidable elidableDynArray[size]; // no warning
188 Elidable elidableNestedArray[1][2][3]; // no warning
190 NonTriviallyDestructible scalar; // no warning
191 NonTriviallyDestructible array[2]; // no warning
192 NonTriviallyDestructible nestedArray[2][2]; // no warning
194 // Copy initialzation gives warning before C++17
195 Foo fooScalar = 1; // cxx98-14-warning {{unused variable 'fooScalar'}}
196 Foo fooArray[] = {1,2}; // expected-warning {{unused variable 'fooArray'}}
197 Foo fooNested[2][2] = { {1,2}, {3,4} }; // expected-warning {{unused variable 'fooNested'}}
200 template<int N>
201 void bar() {
202 NonTriviallyDestructible scaler; // no warning
203 NonTriviallyDestructible array[N]; // no warning
206 void test() {
207 foo(10);
208 bar<2>();
211 } // namespace arrayRecords
213 #if __cplusplus >= 201103L
214 namespace with_constexpr {
215 template <typename T>
216 struct Literal {
217 T i;
218 Literal() = default;
219 constexpr Literal(T i) : i(i) {}
222 struct NoLiteral {
223 int i;
224 NoLiteral() = default;
225 constexpr NoLiteral(int i) : i(i) {}
226 ~NoLiteral() {}
229 static Literal<int> gl1; // expected-warning {{unused variable 'gl1'}}
230 static Literal<int> gl2(1); // expected-warning {{unused variable 'gl2'}}
231 static const Literal<int> gl3(0); // expected-warning {{unused variable 'gl3'}}
233 template <typename T>
234 void test(int i) {
235 Literal<int> l1; // expected-warning {{unused variable 'l1'}}
236 Literal<int> l2(42); // expected-warning {{unused variable 'l2'}}
237 Literal<int> l3(i); // no-warning
238 Literal<T> l4(0); // no-warning
239 NoLiteral nl1; // no-warning
240 NoLiteral nl2(42); // no-warning
244 namespace crash {
245 struct a {
246 a(const char *);
248 template <typename b>
249 void c() {
250 a d(b::e ? "" : "");
254 // Ensure we don't warn on dependent constructor calls.
255 namespace dependent_ctor {
256 struct S {
257 S() = default;
258 S(const S &) = default;
259 S(int);
262 template <typename T>
263 void foo(T &t) {
264 S s{t};
267 #endif
269 // Ensure we do not warn on lifetime extension
270 namespace gh54489 {
272 void f() {
273 const auto &a = NonTriviallyDestructible();
274 const auto &b = a; // expected-warning {{unused variable 'b'}}
275 #if __cplusplus >= 201103L
276 const auto &&c = NonTriviallyDestructible();
277 auto &&d = c; // expected-warning {{unused variable 'd'}}
278 #endif
281 struct S {
282 S() = default;
283 S(const S &) = default;
284 S(int);
287 template <typename T>
288 void foo(T &t) {
289 const auto &extended = S{t};
292 void test_foo() {
293 int i;
294 foo(i);
297 struct RAIIWrapper {
298 RAIIWrapper();
299 ~RAIIWrapper();
302 void RAIIWrapperTest() {
303 auto const guard = RAIIWrapper();
304 auto const &guard2 = RAIIWrapper();
305 auto &&guard3 = RAIIWrapper();
308 } // namespace gh54489
310 // Ensure that -Wunused-variable does not emit warning
311 // on copy constructors with side effects (C++17 and later)
312 #if __cplusplus >= 201703L
313 namespace gh79518 {
315 struct S {
316 S(int);
319 // With an initializer list
320 struct A {
321 int x;
322 A(int x) : x(x) {}
325 void foo() {
326 S s(0); // no warning
327 S s2 = 0; // no warning
328 S s3{0}; // no warning
330 A a = 1; // no warning
333 } // namespace gh79518
334 #endif