1 | // RUN: echo "static void staticFunctionHeader(int i) {;}" > %T/header.h |
2 | // RUN: echo "static void staticFunctionHeader(int /*i*/) {;}" > %T/header-fixed.h |
3 | // RUN: %check_clang_tidy -std=c++11 %s misc-unused-parameters %t -- -header-filter='.*' -- -fno-delayed-template-parsing |
4 | // RUN: diff %T/header.h %T/header-fixed.h |
5 | // FIXME: Make the test work in all language modes. |
6 | |
7 | #include "header.h" |
8 | // CHECK-MESSAGES: header.h:1:38: warning |
9 | |
10 | // Basic removal |
11 | // ============= |
12 | void a(int i) {;} |
13 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters] |
14 | // CHECK-FIXES: {{^}}void a(int /*i*/) {;}{{$}} |
15 | |
16 | void b(int i = 1) {;} |
17 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters] |
18 | // CHECK-FIXES: {{^}}void b(int /*i*/ = 1) {;}{{$}} |
19 | |
20 | void c(int *i) {;} |
21 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: parameter 'i' is unused [misc-unused-parameters] |
22 | // CHECK-FIXES: {{^}}void c(int * /*i*/) {;}{{$}} |
23 | |
24 | void d(int i[]) {;} |
25 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters] |
26 | // CHECK-FIXES: {{^}}void d(int /*i*/[]) {;}{{$}} |
27 | |
28 | void e(int i[1]) {;} |
29 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters] |
30 | // CHECK-FIXES: {{^}}void e(int /*i*/[1]) {;}{{$}} |
31 | |
32 | void f(void (*fn)()) {;} |
33 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: parameter 'fn' is unused [misc-unused-parameters] |
34 | // CHECK-FIXES: {{^}}void f(void (* /*fn*/)()) {;}{{$}} |
35 | |
36 | // Unchanged cases |
37 | // =============== |
38 | void f(int i); // Don't remove stuff in declarations |
39 | void g(int i = 1); |
40 | void h(int i[]); |
41 | void s(int i[1]); |
42 | void u(void (*fn)()); |
43 | void w(int i) { (void)i; } // Don't remove used parameters |
44 | |
45 | bool useLambda(int (*fn)(int)); |
46 | static bool static_var = useLambda(fn: [] (int a) { return a; }); |
47 | |
48 | // Remove parameters of local functions |
49 | // ==================================== |
50 | static void staticFunctionA(int i); |
51 | // CHECK-FIXES: {{^}}static void staticFunctionA(); |
52 | static void staticFunctionA(int i) {;} |
53 | // CHECK-MESSAGES: :[[@LINE-1]]:33: warning |
54 | // CHECK-FIXES: {{^}}static void staticFunctionA() |
55 | |
56 | static void staticFunctionB(int i, int j) { (void)i; } |
57 | // CHECK-MESSAGES: :[[@LINE-1]]:40: warning |
58 | // CHECK-FIXES: {{^}}static void staticFunctionB(int i) |
59 | |
60 | static void staticFunctionC(int i, int j) { (void)j; } |
61 | // CHECK-MESSAGES: :[[@LINE-1]]:33: warning |
62 | // CHECK-FIXES: {{^}}static void staticFunctionC(int j) |
63 | |
64 | static void staticFunctionD(int i, int j, int k) { (void)i; (void)k; } |
65 | // CHECK-MESSAGES: :[[@LINE-1]]:40: warning |
66 | // CHECK-FIXES: {{^}}static void staticFunctionD(int i, int k) |
67 | |
68 | static void staticFunctionE(int i = 4) {;} |
69 | // CHECK-MESSAGES: :[[@LINE-1]]:33: warning |
70 | // CHECK-FIXES: {{^}}static void staticFunctionE() |
71 | |
72 | static void staticFunctionF(int i = 4); |
73 | // CHECK-FIXES: {{^}}static void staticFunctionF(); |
74 | static void staticFunctionF(int i) {;} |
75 | // CHECK-MESSAGES: :[[@LINE-1]]:33: warning |
76 | // CHECK-FIXES: {{^}}static void staticFunctionF() |
77 | |
78 | static void staticFunctionG(int i[]); |
79 | // CHECK-FIXES: {{^}}static void staticFunctionG(); |
80 | static void staticFunctionG(int i[]) {;} |
81 | // CHECK-MESSAGES: :[[@LINE-1]]:33: warning |
82 | // CHECK-FIXES: {{^}}static void staticFunctionG() |
83 | |
84 | static void staticFunctionH(void (*fn)()); |
85 | // CHECK-FIXES: {{^}}static void staticFunctionH(); |
86 | static void staticFunctionH(void (*fn)()) {;} |
87 | // CHECK-MESSAGES: :[[@LINE-1]]:36: warning |
88 | // CHECK-FIXES: {{^}}static void staticFunctionH() |
89 | |
90 | static void someCallSites() { |
91 | staticFunctionA(i: 1); |
92 | // CHECK-FIXES: staticFunctionA(); |
93 | staticFunctionB(i: 1, j: 2); |
94 | // CHECK-FIXES: staticFunctionB(1); |
95 | staticFunctionC(i: 1, j: 2); |
96 | // CHECK-FIXES: staticFunctionC(2); |
97 | staticFunctionD(i: 1, j: 2, k: 3); |
98 | // CHECK-FIXES: staticFunctionD(1, 3); |
99 | staticFunctionE(i: 1); |
100 | // CHECK-FIXES: staticFunctionE(); |
101 | staticFunctionF(i: 1); |
102 | // CHECK-FIXES: staticFunctionF(); |
103 | staticFunctionF(); |
104 | // CHECK-FIXES: staticFunctionF(); |
105 | int t[] = {1}; |
106 | staticFunctionG(i: t); |
107 | // CHECK-FIXES: staticFunctionG(); |
108 | void func(); |
109 | staticFunctionH(fn: &func); |
110 | // CHECK-FIXES: staticFunctionH(); |
111 | } |
112 | |
113 | /* |
114 | * FIXME: This fails because the removals overlap and ClangTidy doesn't apply |
115 | * them. |
116 | * static void bothVarsUnused(int a, int b) {;} |
117 | */ |
118 | |
119 | // Regression test for long variable names and expressions |
120 | // ======================================================= |
121 | static int variableWithLongName1(int LongName1, int LongName2) { |
122 | // CHECK-MESSAGES: :[[@LINE-1]]:53: warning: parameter 'LongName2' is unused |
123 | // CHECK-FIXES: {{^}}static int variableWithLongName1(int LongName1) { |
124 | return LongName1; |
125 | } |
126 | static int variableWithLongName2(int LongName1, int LongName2) { |
127 | // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: parameter 'LongName1' is unused |
128 | // CHECK-FIXES: {{^}}static int variableWithLongName2(int LongName2) { |
129 | return LongName2; |
130 | } |
131 | static void someLongNameCallSites() { |
132 | int LongName1 = 7, LongName2 = 17; |
133 | variableWithLongName1(LongName1, LongName2); |
134 | // CHECK-FIXES: variableWithLongName1(LongName1); |
135 | variableWithLongName2(LongName1, LongName2); |
136 | // CHECK-FIXES: variableWithLongName2(LongName2); |
137 | } |
138 | |
139 | class SomeClass { |
140 | static void f(int i) {;} |
141 | // CHECK-MESSAGES: :[[@LINE-1]]:21: warning |
142 | // CHECK-FIXES: static void f(int /*i*/) {;} |
143 | static void g(int i = 1) {;} |
144 | // CHECK-MESSAGES: :[[@LINE-1]]:21: warning |
145 | // CHECK-FIXES: static void g(int /*i*/ = 1) {;} |
146 | static void h(int i[]) {;} |
147 | // CHECK-MESSAGES: :[[@LINE-1]]:21: warning |
148 | // CHECK-FIXES: static void h(int /*i*/[]) {;} |
149 | static void s(void (*fn)()) {;} |
150 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning |
151 | // CHECK-FIXES: static void s(void (* /*fn*/)()) {;} |
152 | }; |
153 | |
154 | namespace { |
155 | class C { |
156 | public: |
157 | void f(int i); |
158 | // CHECK-FIXES: void f(); |
159 | void g(int i) {;} |
160 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning |
161 | // CHECK-FIXES: void g() {;} |
162 | void h(int i) {;} |
163 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning |
164 | // CHECK-FIXES: void h(int /*i*/) {;} |
165 | void s(int i = 1) {;} |
166 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning |
167 | // CHECK-FIXES: void s(int /*i*/ = 1) {;} |
168 | void u(int i[]) {;} |
169 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning |
170 | // CHECK-FIXES: void u(int /*i*/[]) {;} |
171 | void w(void (*fn)()) {;} |
172 | // CHECK-MESSAGES: :[[@LINE-1]]:17: warning |
173 | // CHECK-FIXES: void w(void (* /*fn*/)()) {;} |
174 | }; |
175 | |
176 | void C::f(int i) {;} |
177 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning |
178 | // CHECK-FIXES: void C::f() {;} |
179 | |
180 | template <typename T> |
181 | void useFunction(T t); |
182 | |
183 | void someMoreCallSites() { |
184 | C c; |
185 | c.f(i: 1); |
186 | // CHECK-FIXES: c.f(); |
187 | c.g(i: 1); |
188 | // CHECK-FIXES: c.g(); |
189 | |
190 | useFunction(t: &C::h); |
191 | useFunction(t: &C::s); |
192 | useFunction(t: &C::u); |
193 | useFunction(t: &C::w); |
194 | } |
195 | |
196 | class Base { |
197 | virtual void f(int i); |
198 | }; |
199 | |
200 | class Derived : public Base { |
201 | void f(int i) override {;} |
202 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning |
203 | // CHECK-FIXES: void f(int /*i*/) override {;} |
204 | }; |
205 | |
206 | } // end namespace |
207 | |
208 | template <typename T> void someFunctionTemplate(T b, T e) { (void)b; (void)e; } |
209 | |
210 | template <typename T> void someFunctionTemplateOneUnusedParam(T b, T e) { (void)e; } |
211 | // CHECK-MESSAGES: :[[@LINE-1]]:65: warning |
212 | // CHECK-FIXES: {{^}}template <typename T> void someFunctionTemplateOneUnusedParam(T /*b*/, T e) { (void)e; } |
213 | |
214 | template <typename T> void someFunctionTemplateAllUnusedParams(T b, T e) {;} |
215 | // CHECK-MESSAGES: :[[@LINE-1]]:66: warning |
216 | // CHECK-MESSAGES: :[[@LINE-2]]:71: warning |
217 | // CHECK-FIXES: {{^}}template <typename T> void someFunctionTemplateAllUnusedParams(T /*b*/, T /*e*/) {;} |
218 | |
219 | static void dontGetConfusedByParametersInFunctionTypes() { void (*F)(int i); } |
220 | |
221 | template <typename T> class Function {}; |
222 | static Function<void(int, int i)> dontGetConfusedByFunctionReturnTypes() { |
223 | return Function<void(int, int)>(); |
224 | } |
225 | |
226 | namespace PR38055 { |
227 | namespace { |
228 | struct a { |
229 | void b(int c) {;} |
230 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: parameter 'c' is unused |
231 | // CHECK-FIXES: {{^}} void b() {;}{{$}} |
232 | }; |
233 | template <class> |
234 | class d { |
235 | a e; |
236 | void f() { e.b(c: 0); } |
237 | }; |
238 | } // namespace |
239 | } // namespace PR38055 |
240 | |
241 | namespace strict_mode_off { |
242 | // Do not warn on empty function bodies. |
243 | void f1(int foo1) {} |
244 | void f2(int foo2) { |
245 | // "empty" in the AST sense, not in textual sense. |
246 | } |
247 | void f3(int foo3) {;} |
248 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: parameter 'foo3' is unused |
249 | // CHECK-FIXES: {{^}}void f3(int /*foo3*/) {;}{{$}} |
250 | |
251 | class E { |
252 | int i; |
253 | |
254 | public: |
255 | E(int j) {} |
256 | }; |
257 | class F { |
258 | int i; |
259 | |
260 | public: |
261 | // Constructor initializer counts as a non-empty body. |
262 | F(int j) : i() {} |
263 | // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'j' is unused |
264 | // CHECK-FIXES: {{^}} F(int /*j*/) : i() {}{{$}} |
265 | }; |
266 | |
267 | class A { |
268 | public: |
269 | A(); |
270 | A(int); |
271 | }; |
272 | class B : public A { |
273 | public: |
274 | B(int i) : A() {} |
275 | // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is unused |
276 | // CHECK-FIXES: {{^}} B(int /*i*/) : A() {}{{$}} |
277 | }; |
278 | } // namespace strict_mode_off |
279 | |
280 | namespace lambda { |
281 | using fn = void(int); |
282 | void f(fn *); |
283 | void test() { |
284 | // CHECK-MESSAGES: :[[@LINE+2]]:12: warning: parameter 'I' is unused |
285 | // CHECK-FIXES: {{^}} f([](int /*I*/) { |
286 | f([](int I) { return; }); |
287 | } |
288 | } // namespace lambda |
289 | |
290 | // Do not warn on naked functions. |
291 | [[gnu::naked]] int nakedFunction(int a, float b, const char *c) { ; } |
292 | __attribute__((naked)) void nakedFunction(int a, int b) { ; } |
293 | |