xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/argument-comment.cpp (revision 89a1d03e2b379e325daa5249411e414bbd995b5e)
1*89a1d03eSRichard // RUN: %check_clang_tidy %s bugprone-argument-comment %t -- -- -I %S/Inputs/argument-comment
2*89a1d03eSRichard 
3*89a1d03eSRichard // FIXME: clang-tidy should provide a -verify mode to make writing these checks
4*89a1d03eSRichard // easier and more accurate.
5*89a1d03eSRichard 
6*89a1d03eSRichard void ffff(int xxxx, int yyyy);
7*89a1d03eSRichard 
8*89a1d03eSRichard void f(int x, int y);
g()9*89a1d03eSRichard void g() {
10*89a1d03eSRichard   // CHECK-NOTES: [[@LINE+4]]:5: warning: argument name 'y' in comment does not match parameter name 'x'
11*89a1d03eSRichard   // CHECK-NOTES: [[@LINE-3]]:12: note: 'x' declared here
12*89a1d03eSRichard   // CHECK-NOTES: [[@LINE+2]]:14: warning: argument name 'z' in comment does not match parameter name 'y'
13*89a1d03eSRichard   // CHECK-NOTES: [[@LINE-5]]:19: note: 'y' declared here
14*89a1d03eSRichard   f(/*y=*/0, /*z=*/0);
15*89a1d03eSRichard   // CHECK-FIXES: {{^}}  f(/*y=*/0, /*z=*/0);
16*89a1d03eSRichard 
17*89a1d03eSRichard   f(/*x=*/1, /*y=*/1);
18*89a1d03eSRichard 
19*89a1d03eSRichard   ffff(0 /*aaaa=*/, /*bbbb*/ 0); // Unsupported formats.
20*89a1d03eSRichard }
21*89a1d03eSRichard 
22*89a1d03eSRichard struct C {
23*89a1d03eSRichard   C(int x, int y);
24*89a1d03eSRichard };
25*89a1d03eSRichard C c(/*x=*/0, /*y=*/0);
26*89a1d03eSRichard 
27*89a1d03eSRichard struct Closure {};
28*89a1d03eSRichard 
29*89a1d03eSRichard template <typename T1, typename T2>
NewCallback(void (* f)(T1,T2),T1 arg1,T2 arg2)30*89a1d03eSRichard Closure *NewCallback(void (*f)(T1, T2), T1 arg1, T2 arg2) { return nullptr; }
31*89a1d03eSRichard 
32*89a1d03eSRichard template <typename T1, typename T2>
NewPermanentCallback(void (* f)(T1,T2),T1 arg1,T2 arg2)33*89a1d03eSRichard Closure *NewPermanentCallback(void (*f)(T1, T2), T1 arg1, T2 arg2) { return nullptr; }
34*89a1d03eSRichard 
h()35*89a1d03eSRichard void h() {
36*89a1d03eSRichard   (void)NewCallback(&ffff, /*xxxx=*/11, /*yyyy=*/22);
37*89a1d03eSRichard   (void)NewPermanentCallback(&ffff, /*xxxx=*/11, /*yyyy=*/22);
38*89a1d03eSRichard }
39*89a1d03eSRichard 
40*89a1d03eSRichard template<typename... Args>
41*89a1d03eSRichard void variadic(Args&&... args);
42*89a1d03eSRichard 
43*89a1d03eSRichard template<typename... Args>
44*89a1d03eSRichard void variadic2(int zzz, Args&&... args);
45*89a1d03eSRichard 
templates()46*89a1d03eSRichard void templates() {
47*89a1d03eSRichard   variadic(/*xxx=*/0, /*yyy=*/1);
48*89a1d03eSRichard   variadic2(/*zzU=*/0, /*xxx=*/1, /*yyy=*/2);
49*89a1d03eSRichard   // CHECK-NOTES: [[@LINE-1]]:13: warning: argument name 'zzU' in comment does not match parameter name 'zzz'
50*89a1d03eSRichard   // CHECK-NOTES: :[[@LINE-6]]:20: note: 'zzz' declared here
51*89a1d03eSRichard   // CHECK-FIXES: variadic2(/*zzz=*/0, /*xxx=*/1, /*yyy=*/2);
52*89a1d03eSRichard }
53*89a1d03eSRichard 
54*89a1d03eSRichard #define FALSE 0
55*89a1d03eSRichard void qqq(bool aaa);
f2()56*89a1d03eSRichard void f2() { qqq(/*bbb=*/FALSE); }
57*89a1d03eSRichard // CHECK-NOTES: [[@LINE-1]]:17: warning: argument name 'bbb' in comment does not match parameter name 'aaa'
58*89a1d03eSRichard // CHECK-NOTES: [[@LINE-3]]:15: note: 'aaa' declared here
59*89a1d03eSRichard // CHECK-FIXES: void f2() { qqq(/*bbb=*/FALSE); }
60*89a1d03eSRichard 
61*89a1d03eSRichard void f3(bool _with_underscores_);
ignores_underscores()62*89a1d03eSRichard void ignores_underscores() {
63*89a1d03eSRichard   f3(/*With_Underscores=*/false);
64*89a1d03eSRichard }
65*89a1d03eSRichard 
66*89a1d03eSRichard namespace IgnoresImplicit {
67*89a1d03eSRichard struct S {
68*89a1d03eSRichard   S(int x);
69*89a1d03eSRichard   int x;
70*89a1d03eSRichard };
71*89a1d03eSRichard 
72*89a1d03eSRichard struct T {
73*89a1d03eSRichard   // Use two arguments (one defaulted) because simplistic check for implicit
74*89a1d03eSRichard   // constructor looks for only one argument. We need to default the argument so
75*89a1d03eSRichard   // that it will still be triggered implicitly.  This is not contrived -- it
76*89a1d03eSRichard   // comes up in real code, for example std::set(std::initializer_list...).
77*89a1d03eSRichard   T(S s, int y = 0);
78*89a1d03eSRichard };
79*89a1d03eSRichard 
80*89a1d03eSRichard void k(T arg1);
81*89a1d03eSRichard 
mynewtest()82*89a1d03eSRichard void mynewtest() {
83*89a1d03eSRichard   int foo = 3;
84*89a1d03eSRichard   k(/*arg1=*/S(foo));
85*89a1d03eSRichard }
86*89a1d03eSRichard } // namespace IgnoresImplicit
87*89a1d03eSRichard 
88*89a1d03eSRichard namespace ThisEditDistanceAboveThreshold {
89*89a1d03eSRichard void f4(int xxx);
g()90*89a1d03eSRichard void g() { f4(/*xyz=*/0); }
91*89a1d03eSRichard // CHECK-NOTES: [[@LINE-1]]:15: warning: argument name 'xyz' in comment does not match parameter name 'xxx'
92*89a1d03eSRichard // CHECK-NOTES: [[@LINE-3]]:13: note: 'xxx' declared here
93*89a1d03eSRichard // CHECK-FIXES: void g() { f4(/*xyz=*/0); }
94*89a1d03eSRichard }
95*89a1d03eSRichard 
96*89a1d03eSRichard namespace OtherEditDistanceAboveThreshold {
97*89a1d03eSRichard void f5(int xxx, int yyy);
g()98*89a1d03eSRichard void g() { f5(/*Zxx=*/0, 0); }
99*89a1d03eSRichard // CHECK-NOTES: [[@LINE-1]]:15: warning: argument name 'Zxx' in comment does not match parameter name 'xxx'
100*89a1d03eSRichard // CHECK-NOTES: [[@LINE-3]]:13: note: 'xxx' declared here
101*89a1d03eSRichard // CHECK-FIXES: void g() { f5(/*xxx=*/0, 0); }
102*89a1d03eSRichard struct C2 {
103*89a1d03eSRichard   C2(int xxx, int yyy);
104*89a1d03eSRichard };
105*89a1d03eSRichard C2 c2(/*Zxx=*/0, 0);
106*89a1d03eSRichard // CHECK-NOTES: [[@LINE-1]]:7: warning: argument name 'Zxx' in comment does not match parameter name 'xxx'
107*89a1d03eSRichard // CHECK-NOTES: [[@LINE-4]]:10: note: 'xxx' declared here
108*89a1d03eSRichard // CHECK-FIXES: C2 c2(/*xxx=*/0, 0);
109*89a1d03eSRichard }
110*89a1d03eSRichard 
111*89a1d03eSRichard namespace OtherEditDistanceBelowThreshold {
112*89a1d03eSRichard void f6(int xxx, int yyy);
g()113*89a1d03eSRichard void g() { f6(/*xxy=*/0, 0); }
114*89a1d03eSRichard // CHECK-NOTES: [[@LINE-1]]:15: warning: argument name 'xxy' in comment does not match parameter name 'xxx'
115*89a1d03eSRichard // CHECK-NOTES: [[@LINE-3]]:13: note: 'xxx' declared here
116*89a1d03eSRichard // CHECK-FIXES: void g() { f6(/*xxy=*/0, 0); }
117*89a1d03eSRichard }
118*89a1d03eSRichard 
119*89a1d03eSRichard 
120*89a1d03eSRichard namespace std {
121*89a1d03eSRichard template <typename T>
122*89a1d03eSRichard class vector {
123*89a1d03eSRichard public:
124*89a1d03eSRichard   void assign(int __n, const T &__val);
125*89a1d03eSRichard };
126*89a1d03eSRichard template<typename T>
127*89a1d03eSRichard void swap(T& __a, T& __b);
128*89a1d03eSRichard } // namespace std
129*89a1d03eSRichard namespace ignore_std_functions {
test(int a,int b)130*89a1d03eSRichard void test(int a, int b) {
131*89a1d03eSRichard   std::vector<int> s;
132*89a1d03eSRichard   // verify the check is not fired on std functions.
133*89a1d03eSRichard   s.assign(1, /*value=*/2);
134*89a1d03eSRichard   std::swap(a, /*num=*/b);
135*89a1d03eSRichard }
136*89a1d03eSRichard } // namespace ignore_std_functions
137*89a1d03eSRichard 
138*89a1d03eSRichard namespace regular_header {
139*89a1d03eSRichard #include "header-with-decl.h"
test()140*89a1d03eSRichard void test() {
141*89a1d03eSRichard   my_header_function(/*not_arg=*/1);
142*89a1d03eSRichard // CHECK-NOTES: [[@LINE-1]]:22: warning: argument name 'not_arg' in comment does not match parameter name 'arg'
143*89a1d03eSRichard // CHECK-NOTES: header-with-decl.h:1:29: note: 'arg' declared here
144*89a1d03eSRichard // CHECK-FIXES: my_header_function(/*not_arg=*/1);
145*89a1d03eSRichard }
146*89a1d03eSRichard } // namespace regular_header
147*89a1d03eSRichard 
148*89a1d03eSRichard namespace system_header {
149*89a1d03eSRichard #include "system-header-with-decl.h"
test()150*89a1d03eSRichard void test() {
151*89a1d03eSRichard   my_system_header_function(/*not_arg=*/1);
152*89a1d03eSRichard }
153*89a1d03eSRichard } // namespace system_header
154*89a1d03eSRichard 
testInvalidSlocCxxConstructExpr()155*89a1d03eSRichard void testInvalidSlocCxxConstructExpr() {
156*89a1d03eSRichard   __builtin_va_list __args;
157*89a1d03eSRichard   // __builtin_va_list has no defination in any source file
158*89a1d03eSRichard }
159