xref: /llvm-project/clang/test/SemaCXX/warn-unused-variables.cpp (revision 7339c0f782d5c70e0928f8991b0c05338a90c84c)
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 -std=gnu++11 %s
3 template<typename T> void f() {
4   T t;
5   t = 17;
6 }
7 
8 // PR5407
9 struct A { A(); };
10 struct B { ~B(); };
11 void f() {
12   A a;
13   B b;
14 }
15 
16 // PR5531
17 namespace PR5531 {
18   struct A {
19   };
20 
21   struct B {
22     B(int);
23   };
24 
25   struct C {
26     ~C();
27   };
28 
29   void test() {
30     A();
31     B(17);
32     C();
33   }
34 }
35 
36 template<typename T>
37 struct X0 { };
38 
39 template<typename T>
40 void test_dependent_init(T *p) {
41   X0<int> i(p);
42   (void)i;
43 }
44 
45 void unused_local_static() {
46   static int x = 0;
47   static int y = 0; // expected-warning{{unused variable 'y'}}
48 #pragma unused(x)
49   static __attribute__((used)) int z;
50   static __attribute__((unused)) int w;
51   [[maybe_unused]] static int v;
52 }
53 
54 // PR10168
55 namespace PR10168 {
56   // We expect a warning in the definition only for non-dependent variables, and
57   // a warning in the instantiation only for dependent variables.
58   template<typename T>
59   struct S {
60     void f() {
61       int a; // expected-warning {{unused variable 'a'}}
62       T b; // expected-warning 2{{unused variable 'b'}}
63     }
64   };
65 
66   template<typename T>
67   void f() {
68     int a; // expected-warning {{unused variable 'a'}}
69     T b; // expected-warning 2{{unused variable 'b'}}
70   }
71 
72   void g() {
73     S<int>().f(); // expected-note {{here}}
74     S<char>().f(); // expected-note {{here}}
75     f<int>(); // expected-note {{here}}
76     f<char>(); // expected-note {{here}}
77   }
78 }
79 
80 namespace PR11550 {
81   struct S1 {
82     S1();
83   };
84   S1 makeS1();
85   void testS1(S1 a) {
86     // This constructor call can be elided.
87     S1 x = makeS1(); // expected-warning {{unused variable 'x'}}
88 
89     // This one cannot, so no warning.
90     S1 y;
91 
92     // This call cannot, but the constructor is trivial.
93     S1 z = a; // expected-warning {{unused variable 'z'}}
94   }
95 
96   // The same is true even when we know thet constructor has side effects.
97   void foo();
98   struct S2 {
99     S2() {
100       foo();
101     }
102   };
103   S2 makeS2();
104   void testS2(S2 a) {
105     S2 x = makeS2(); // expected-warning {{unused variable 'x'}}
106     S2 y;
107     S2 z = a; // expected-warning {{unused variable 'z'}}
108   }
109 
110   // Or when the constructor is not declared by the user.
111   struct S3 {
112     S1 m;
113   };
114   S3 makeS3();
115   void testS3(S3 a) {
116     S3 x = makeS3(); // expected-warning {{unused variable 'x'}}
117     S3 y;
118     S3 z = a; // expected-warning {{unused variable 'z'}}
119   }
120 }
121 
122 namespace PR19305 {
123   template<typename T> int n = 0; // no warning
124   int a = n<int>;
125 
126   template<typename T> const int l = 0; // no warning
127   int b = l<int>;
128 
129   // PR19558
130   template<typename T> const int o = 0; // no warning
131   template<typename T> const int o<T*> = 0; // no warning
132   int c = o<int*>;
133 
134   template<> int o<void> = 0; // no warning
135   int d = o<void>;
136 
137   // FIXME: It'd be nice to warn here.
138   template<typename T> int m = 0;
139   template<typename T> int m<T*> = 0;
140 
141   // This has external linkage, so could be referenced by a declaration in a
142   // different translation unit.
143   template<> const int m<void> = 0; // no warning
144 }
145 
146 namespace ctor_with_cleanups {
147   struct S1 {
148     ~S1();
149   };
150   struct S2 {
151     S2(const S1&);
152   };
153   void func() {
154     S2 s((S1()));
155   }
156 }
157 
158 #include "Inputs/warn-unused-variables.h"
159 
160 class NonTriviallyDestructible {
161 public:
162   ~NonTriviallyDestructible() {}
163 };
164 
165 namespace arrayRecords {
166 
167 struct Foo {
168   int x;
169   Foo(int x) : x(x) {}
170 };
171 
172 struct Elidable {
173   Elidable();
174 };
175 
176 void foo(int size) {
177   Elidable elidable; // no warning
178   Elidable elidableArray[2]; // no warning
179   Elidable elidableDynArray[size]; // no warning
180   Elidable elidableNestedArray[1][2][3]; // no warning
181 
182   NonTriviallyDestructible scalar; // no warning
183   NonTriviallyDestructible array[2];  // no warning
184   NonTriviallyDestructible nestedArray[2][2]; // no warning
185 
186   Foo fooScalar = 1; // expected-warning {{unused variable 'fooScalar'}}
187   Foo fooArray[] = {1,2}; // expected-warning {{unused variable 'fooArray'}}
188   Foo fooNested[2][2] = { {1,2}, {3,4} }; // expected-warning {{unused variable 'fooNested'}}
189 }
190 
191 template<int N>
192 void bar() {
193   NonTriviallyDestructible scaler; // no warning
194   NonTriviallyDestructible array[N]; // no warning
195 }
196 
197 void test() {
198   foo(10);
199   bar<2>();
200 }
201 
202 } // namespace arrayRecords
203 
204 #if __cplusplus >= 201103L
205 namespace with_constexpr {
206 template <typename T>
207 struct Literal {
208   T i;
209   Literal() = default;
210   constexpr Literal(T i) : i(i) {}
211 };
212 
213 struct NoLiteral {
214   int i;
215   NoLiteral() = default;
216   constexpr NoLiteral(int i) : i(i) {}
217   ~NoLiteral() {}
218 };
219 
220 static Literal<int> gl1;          // expected-warning {{unused variable 'gl1'}}
221 static Literal<int> gl2(1);       // expected-warning {{unused variable 'gl2'}}
222 static const Literal<int> gl3(0); // expected-warning {{unused variable 'gl3'}}
223 
224 template <typename T>
225 void test(int i) {
226   Literal<int> l1;     // expected-warning {{unused variable 'l1'}}
227   Literal<int> l2(42); // expected-warning {{unused variable 'l2'}}
228   Literal<int> l3(i);  // no-warning
229   Literal<T> l4(0);    // no-warning
230   NoLiteral nl1;       // no-warning
231   NoLiteral nl2(42);   // no-warning
232 }
233 }
234 
235 namespace crash {
236 struct a {
237   a(const char *);
238 };
239 template <typename b>
240 void c() {
241   a d(b::e ? "" : "");
242 }
243 }
244 
245 // Ensure we don't warn on dependent constructor calls.
246 namespace dependent_ctor {
247 struct S {
248   S() = default;
249   S(const S &) = default;
250   S(int);
251 };
252 
253 template <typename T>
254 void foo(T &t) {
255   S s{t};
256 }
257 }
258 #endif
259 
260 // Ensure we do not warn on lifetime extension
261 namespace gh54489 {
262 
263 void f() {
264   const auto &a = NonTriviallyDestructible();
265   const auto &b = a; // expected-warning {{unused variable 'b'}}
266 #if __cplusplus >= 201103L
267   const auto &&c = NonTriviallyDestructible();
268   auto &&d = c; // expected-warning {{unused variable 'd'}}
269 #endif
270 }
271 
272 struct S {
273   S() = default;
274   S(const S &) = default;
275   S(int);
276 };
277 
278 template <typename T>
279 void foo(T &t) {
280   const auto &extended = S{t};
281 }
282 
283 void test_foo() {
284   int i;
285   foo(i);
286 }
287 
288 struct RAIIWrapper {
289   RAIIWrapper();
290   ~RAIIWrapper();
291 };
292 
293 void RAIIWrapperTest() {
294   auto const guard = RAIIWrapper();
295   auto const &guard2 = RAIIWrapper();
296   auto &&guard3 = RAIIWrapper();
297 }
298 
299 } // namespace gh54489
300