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