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