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