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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters.cpp