xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters.cpp (revision 1b897f737df2097f8fee1b203676ea7f01dff06d)
189a1d03eSRichard // RUN: echo "static void staticFunctionHeader(int i) {;}" > %T/header.h
289a1d03eSRichard // RUN: echo "static void staticFunctionHeader(int  /*i*/) {;}" > %T/header-fixed.h
389a1d03eSRichard // RUN: %check_clang_tidy -std=c++11 %s misc-unused-parameters %t -- -header-filter='.*' -- -fno-delayed-template-parsing
489a1d03eSRichard // RUN: diff %T/header.h %T/header-fixed.h
589a1d03eSRichard // FIXME: Make the test work in all language modes.
689a1d03eSRichard 
789a1d03eSRichard #include "header.h"
889a1d03eSRichard // CHECK-MESSAGES: header.h:1:38: warning
989a1d03eSRichard 
1089a1d03eSRichard // Basic removal
1189a1d03eSRichard // =============
1289a1d03eSRichard void a(int i) {;}
1389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
1489a1d03eSRichard // CHECK-FIXES: {{^}}void a(int  /*i*/) {;}{{$}}
1589a1d03eSRichard 
1689a1d03eSRichard void b(int i = 1) {;}
1789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
1889a1d03eSRichard // CHECK-FIXES: {{^}}void b(int  /*i*/ = 1) {;}{{$}}
1989a1d03eSRichard 
2089a1d03eSRichard void c(int *i) {;}
2189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: parameter 'i' is unused [misc-unused-parameters]
2289a1d03eSRichard // CHECK-FIXES: {{^}}void c(int * /*i*/) {;}{{$}}
2389a1d03eSRichard 
2489a1d03eSRichard void d(int i[]) {;}
2589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
2689a1d03eSRichard // CHECK-FIXES: {{^}}void d(int  /*i*/[]) {;}{{$}}
2789a1d03eSRichard 
2889a1d03eSRichard void e(int i[1]) {;}
2989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
3089a1d03eSRichard // CHECK-FIXES: {{^}}void e(int  /*i*/[1]) {;}{{$}}
3189a1d03eSRichard 
3289a1d03eSRichard void f(void (*fn)()) {;}
3389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: parameter 'fn' is unused [misc-unused-parameters]
3489a1d03eSRichard // CHECK-FIXES: {{^}}void f(void (* /*fn*/)()) {;}{{$}}
3589a1d03eSRichard 
36*1b897f73SMaksim Ivanov int *k([[clang::lifetimebound]] int *i) {;}
37*1b897f73SMaksim Ivanov // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: parameter 'i' is unused [misc-unused-parameters]
38*1b897f73SMaksim Ivanov // CHECK-FIXES: {{^}}int *k({{\[\[clang::lifetimebound\]\]}} int * /*i*/) {;}{{$}}
39*1b897f73SMaksim Ivanov 
40*1b897f73SMaksim Ivanov #define ATTR_BEFORE(x) [[clang::lifetimebound]] x
41*1b897f73SMaksim Ivanov int* m(ATTR_BEFORE(const int *i)) { return nullptr; }
42*1b897f73SMaksim Ivanov // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: parameter 'i' is unused [misc-unused-parameters]
43*1b897f73SMaksim Ivanov // CHECK-FIXES: {{^}}int* m(ATTR_BEFORE(const int * /*i*/)) { return nullptr; }{{$}}
44*1b897f73SMaksim Ivanov #undef ATTR_BEFORE
45*1b897f73SMaksim Ivanov 
4689a1d03eSRichard // Unchanged cases
4789a1d03eSRichard // ===============
4889a1d03eSRichard void f(int i); // Don't remove stuff in declarations
4989a1d03eSRichard void g(int i = 1);
5089a1d03eSRichard void h(int i[]);
5189a1d03eSRichard void s(int i[1]);
5289a1d03eSRichard void u(void (*fn)());
5389a1d03eSRichard void w(int i) { (void)i; } // Don't remove used parameters
5489a1d03eSRichard 
55*1b897f73SMaksim Ivanov // Don't reanchor the attribute to the type:
56*1b897f73SMaksim Ivanov int *x(int *i [[clang::lifetimebound]]) { return nullptr; }
57*1b897f73SMaksim Ivanov #define ATTR_AFTER(x) x [[clang::lifetimebound]]
58*1b897f73SMaksim Ivanov int* y(ATTR_AFTER(const int *i)) { return nullptr; }
59*1b897f73SMaksim Ivanov #undef ATTR_AFTER
60*1b897f73SMaksim Ivanov 
6189a1d03eSRichard bool useLambda(int (*fn)(int));
6289a1d03eSRichard static bool static_var = useLambda([] (int a) { return a; });
6389a1d03eSRichard 
6489a1d03eSRichard // Remove parameters of local functions
6589a1d03eSRichard // ====================================
6689a1d03eSRichard static void staticFunctionA(int i);
6789a1d03eSRichard // CHECK-FIXES: {{^}}static void staticFunctionA();
6889a1d03eSRichard static void staticFunctionA(int i) {;}
6989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:33: warning
7089a1d03eSRichard // CHECK-FIXES: {{^}}static void staticFunctionA()
7189a1d03eSRichard 
7289a1d03eSRichard static void staticFunctionB(int i, int j) { (void)i; }
7389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:40: warning
7489a1d03eSRichard // CHECK-FIXES: {{^}}static void staticFunctionB(int i)
7589a1d03eSRichard 
7689a1d03eSRichard static void staticFunctionC(int i, int j) { (void)j; }
7789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:33: warning
7889a1d03eSRichard // CHECK-FIXES: {{^}}static void staticFunctionC(int j)
7989a1d03eSRichard 
8089a1d03eSRichard static void staticFunctionD(int i, int j, int k) { (void)i; (void)k; }
8189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:40: warning
8289a1d03eSRichard // CHECK-FIXES: {{^}}static void staticFunctionD(int i, int k)
8389a1d03eSRichard 
8489a1d03eSRichard static void staticFunctionE(int i = 4) {;}
8589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:33: warning
8689a1d03eSRichard // CHECK-FIXES: {{^}}static void staticFunctionE()
8789a1d03eSRichard 
8889a1d03eSRichard static void staticFunctionF(int i = 4);
8989a1d03eSRichard // CHECK-FIXES: {{^}}static void staticFunctionF();
9089a1d03eSRichard static void staticFunctionF(int i) {;}
9189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:33: warning
9289a1d03eSRichard // CHECK-FIXES: {{^}}static void staticFunctionF()
9389a1d03eSRichard 
9489a1d03eSRichard static void staticFunctionG(int i[]);
9589a1d03eSRichard // CHECK-FIXES: {{^}}static void staticFunctionG();
9689a1d03eSRichard static void staticFunctionG(int i[]) {;}
9789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:33: warning
9889a1d03eSRichard // CHECK-FIXES: {{^}}static void staticFunctionG()
9989a1d03eSRichard 
10089a1d03eSRichard static void staticFunctionH(void (*fn)());
10189a1d03eSRichard // CHECK-FIXES: {{^}}static void staticFunctionH();
10289a1d03eSRichard static void staticFunctionH(void (*fn)()) {;}
10389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:36: warning
10489a1d03eSRichard // CHECK-FIXES: {{^}}static void staticFunctionH()
10589a1d03eSRichard 
10689a1d03eSRichard static void someCallSites() {
10789a1d03eSRichard   staticFunctionA(1);
10889a1d03eSRichard // CHECK-FIXES: staticFunctionA();
10989a1d03eSRichard   staticFunctionB(1, 2);
11089a1d03eSRichard // CHECK-FIXES: staticFunctionB(1);
11189a1d03eSRichard   staticFunctionC(1, 2);
11289a1d03eSRichard // CHECK-FIXES: staticFunctionC(2);
11389a1d03eSRichard   staticFunctionD(1, 2, 3);
11489a1d03eSRichard // CHECK-FIXES: staticFunctionD(1, 3);
11589a1d03eSRichard   staticFunctionE(1);
11689a1d03eSRichard // CHECK-FIXES: staticFunctionE();
11789a1d03eSRichard   staticFunctionF(1);
11889a1d03eSRichard // CHECK-FIXES: staticFunctionF();
11989a1d03eSRichard   staticFunctionF();
12089a1d03eSRichard // CHECK-FIXES: staticFunctionF();
12189a1d03eSRichard   int t[] = {1};
12289a1d03eSRichard   staticFunctionG(t);
12389a1d03eSRichard // CHECK-FIXES: staticFunctionG();
12489a1d03eSRichard   void func();
12589a1d03eSRichard   staticFunctionH(&func);
12689a1d03eSRichard // CHECK-FIXES: staticFunctionH();
12789a1d03eSRichard }
12889a1d03eSRichard 
12989a1d03eSRichard /*
13089a1d03eSRichard  * FIXME: This fails because the removals overlap and ClangTidy doesn't apply
13189a1d03eSRichard  *        them.
13289a1d03eSRichard  * static void bothVarsUnused(int a, int b) {;}
13389a1d03eSRichard  */
13489a1d03eSRichard 
13589a1d03eSRichard // Regression test for long variable names and expressions
13689a1d03eSRichard // =======================================================
13789a1d03eSRichard static int variableWithLongName1(int LongName1, int LongName2) {
13889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:53: warning: parameter 'LongName2' is unused
13989a1d03eSRichard // CHECK-FIXES: {{^}}static int variableWithLongName1(int LongName1) {
14089a1d03eSRichard   return LongName1;
14189a1d03eSRichard }
14289a1d03eSRichard static int variableWithLongName2(int LongName1, int LongName2) {
14389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: parameter 'LongName1' is unused
14489a1d03eSRichard // CHECK-FIXES: {{^}}static int variableWithLongName2(int LongName2) {
14589a1d03eSRichard   return LongName2;
14689a1d03eSRichard }
14789a1d03eSRichard static void someLongNameCallSites() {
14889a1d03eSRichard   int LongName1 = 7, LongName2 = 17;
14989a1d03eSRichard   variableWithLongName1(LongName1, LongName2);
15089a1d03eSRichard // CHECK-FIXES: variableWithLongName1(LongName1);
15189a1d03eSRichard   variableWithLongName2(LongName1, LongName2);
15289a1d03eSRichard // CHECK-FIXES: variableWithLongName2(LongName2);
15389a1d03eSRichard }
15489a1d03eSRichard 
15589a1d03eSRichard class SomeClass {
15689a1d03eSRichard   static void f(int i) {;}
15789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:21: warning
15889a1d03eSRichard // CHECK-FIXES: static void f(int  /*i*/) {;}
15989a1d03eSRichard   static void g(int i = 1) {;}
16089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:21: warning
16189a1d03eSRichard // CHECK-FIXES: static void g(int  /*i*/ = 1) {;}
16289a1d03eSRichard   static void h(int i[]) {;}
16389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:21: warning
16489a1d03eSRichard // CHECK-FIXES: static void h(int  /*i*/[]) {;}
16589a1d03eSRichard   static void s(void (*fn)()) {;}
16689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:24: warning
16789a1d03eSRichard // CHECK-FIXES: static void s(void (* /*fn*/)()) {;}
16889a1d03eSRichard };
16989a1d03eSRichard 
17089a1d03eSRichard namespace {
17189a1d03eSRichard class C {
17289a1d03eSRichard public:
17389a1d03eSRichard   void f(int i);
17489a1d03eSRichard // CHECK-FIXES: void f();
17589a1d03eSRichard   void g(int i) {;}
17689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning
17789a1d03eSRichard // CHECK-FIXES: void g() {;}
17889a1d03eSRichard   void h(int i) {;}
17989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning
18089a1d03eSRichard // CHECK-FIXES: void h(int  /*i*/) {;}
18189a1d03eSRichard   void s(int i = 1) {;}
18289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning
18389a1d03eSRichard // CHECK-FIXES: void s(int  /*i*/ = 1) {;}
18489a1d03eSRichard   void u(int i[]) {;}
18589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning
18689a1d03eSRichard // CHECK-FIXES: void u(int  /*i*/[]) {;}
18789a1d03eSRichard   void w(void (*fn)()) {;}
18889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:17: warning
18989a1d03eSRichard // CHECK-FIXES: void w(void (* /*fn*/)()) {;}
19089a1d03eSRichard };
19189a1d03eSRichard 
19289a1d03eSRichard void C::f(int i) {;}
19389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:15: warning
19489a1d03eSRichard // CHECK-FIXES: void C::f() {;}
19589a1d03eSRichard 
19689a1d03eSRichard template <typename T>
19789a1d03eSRichard void useFunction(T t);
19889a1d03eSRichard 
19989a1d03eSRichard void someMoreCallSites() {
20089a1d03eSRichard   C c;
20189a1d03eSRichard   c.f(1);
20289a1d03eSRichard // CHECK-FIXES: c.f();
20389a1d03eSRichard   c.g(1);
20489a1d03eSRichard // CHECK-FIXES: c.g();
20589a1d03eSRichard 
20689a1d03eSRichard   useFunction(&C::h);
20789a1d03eSRichard   useFunction(&C::s);
20889a1d03eSRichard   useFunction(&C::u);
20989a1d03eSRichard   useFunction(&C::w);
21089a1d03eSRichard }
21189a1d03eSRichard 
21289a1d03eSRichard class Base {
21389a1d03eSRichard   virtual void f(int i);
21489a1d03eSRichard };
21589a1d03eSRichard 
21689a1d03eSRichard class Derived : public Base {
21789a1d03eSRichard   void f(int i) override {;}
21889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning
21989a1d03eSRichard // CHECK-FIXES: void f(int  /*i*/) override {;}
22089a1d03eSRichard };
22189a1d03eSRichard 
22289a1d03eSRichard } // end namespace
22389a1d03eSRichard 
22489a1d03eSRichard template <typename T> void someFunctionTemplate(T b, T e) { (void)b; (void)e; }
22589a1d03eSRichard 
22689a1d03eSRichard template <typename T> void someFunctionTemplateOneUnusedParam(T b, T e) { (void)e; }
22789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:65: warning
22889a1d03eSRichard // CHECK-FIXES: {{^}}template <typename T> void someFunctionTemplateOneUnusedParam(T  /*b*/, T e) { (void)e; }
22989a1d03eSRichard 
23089a1d03eSRichard template <typename T> void someFunctionTemplateAllUnusedParams(T b, T e) {;}
23189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:66: warning
23289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:71: warning
23389a1d03eSRichard // CHECK-FIXES: {{^}}template <typename T> void someFunctionTemplateAllUnusedParams(T  /*b*/, T  /*e*/) {;}
23489a1d03eSRichard 
23589a1d03eSRichard static void dontGetConfusedByParametersInFunctionTypes() { void (*F)(int i); }
23689a1d03eSRichard 
23789a1d03eSRichard template <typename T> class Function {};
23889a1d03eSRichard static Function<void(int, int i)> dontGetConfusedByFunctionReturnTypes() {
23989a1d03eSRichard   return Function<void(int, int)>();
24089a1d03eSRichard }
24189a1d03eSRichard 
24289a1d03eSRichard namespace PR38055 {
24389a1d03eSRichard namespace {
24489a1d03eSRichard struct a {
24589a1d03eSRichard   void b(int c) {;}
24689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: parameter 'c' is unused
24789a1d03eSRichard // CHECK-FIXES: {{^}}  void b() {;}{{$}}
24889a1d03eSRichard };
24989a1d03eSRichard template <class>
25089a1d03eSRichard class d {
25189a1d03eSRichard   a e;
25289a1d03eSRichard   void f() { e.b(0); }
25389a1d03eSRichard };
25489a1d03eSRichard }  // namespace
25589a1d03eSRichard }  // namespace PR38055
25689a1d03eSRichard 
25789a1d03eSRichard namespace strict_mode_off {
25889a1d03eSRichard // Do not warn on empty function bodies.
25989a1d03eSRichard void f1(int foo1) {}
26089a1d03eSRichard void f2(int foo2) {
26189a1d03eSRichard   // "empty" in the AST sense, not in textual sense.
26289a1d03eSRichard }
26389a1d03eSRichard void f3(int foo3) {;}
26489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: parameter 'foo3' is unused
26589a1d03eSRichard // CHECK-FIXES: {{^}}void f3(int  /*foo3*/) {;}{{$}}
26689a1d03eSRichard 
26789a1d03eSRichard class E {
26889a1d03eSRichard   int i;
26989a1d03eSRichard 
27089a1d03eSRichard public:
27189a1d03eSRichard   E(int j) {}
27289a1d03eSRichard };
27389a1d03eSRichard class F {
27489a1d03eSRichard   int i;
27589a1d03eSRichard 
27689a1d03eSRichard public:
27789a1d03eSRichard   // Constructor initializer counts as a non-empty body.
27889a1d03eSRichard   F(int j) : i() {}
27989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'j' is unused
28089a1d03eSRichard // CHECK-FIXES: {{^}}  F(int  /*j*/) : i() {}{{$}}
28189a1d03eSRichard };
28289a1d03eSRichard 
28389a1d03eSRichard class A {
28489a1d03eSRichard public:
28589a1d03eSRichard   A();
28689a1d03eSRichard   A(int);
28789a1d03eSRichard };
28889a1d03eSRichard class B : public A {
28989a1d03eSRichard public:
29089a1d03eSRichard   B(int i) : A() {}
29189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is unused
29289a1d03eSRichard // CHECK-FIXES: {{^}}  B(int  /*i*/) : A() {}{{$}}
29389a1d03eSRichard };
29489a1d03eSRichard } // namespace strict_mode_off
29589a1d03eSRichard 
29689a1d03eSRichard namespace lambda {
29789a1d03eSRichard using fn = void(int);
29889a1d03eSRichard void f(fn *);
29989a1d03eSRichard void test() {
30089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+2]]:12: warning: parameter 'I' is unused
30189a1d03eSRichard   // CHECK-FIXES: {{^}}  f([](int  /*I*/) {
30289a1d03eSRichard   f([](int I) { return; });
30389a1d03eSRichard }
30489a1d03eSRichard } // namespace lambda
30589a1d03eSRichard 
30689a1d03eSRichard // Do not warn on naked functions.
30789a1d03eSRichard [[gnu::naked]] int nakedFunction(int a, float b, const char *c) { ; }
30889a1d03eSRichard __attribute__((naked)) void nakedFunction(int a, int b) { ; }
309