1// RUN: %check_clang_tidy %s bugprone-argument-comment %t -- -- -I %S/Inputs/argument-comment
2
3// FIXME: clang-tidy should provide a -verify mode to make writing these checks
4// easier and more accurate.
5
6void ffff(int xxxx, int yyyy);
7
8void f(int x, int y);
9void 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=*/x: 0, /*z=*/y: 0);
15 // CHECK-FIXES: {{^}} f(/*y=*/0, /*z=*/0);
16
17 f(/*x=*/1, /*y=*/1);
18
19 ffff(xxxx: 0 /*aaaa=*/, /*bbbb*/ yyyy: 0); // Unsupported formats.
20}
21
22struct C {
23 C(int x, int y);
24};
25C c(/*x=*/0, /*y=*/0);
26
27struct Closure {};
28
29template <typename T1, typename T2>
30Closure *NewCallback(void (*f)(T1, T2), T1 arg1, T2 arg2) { return nullptr; }
31
32template <typename T1, typename T2>
33Closure *NewPermanentCallback(void (*f)(T1, T2), T1 arg1, T2 arg2) { return nullptr; }
34
35void h() {
36 (void)NewCallback(f: &ffff, /*xxxx=*/arg1: 11, /*yyyy=*/arg2: 22);
37 (void)NewPermanentCallback(f: &ffff, /*xxxx=*/arg1: 11, /*yyyy=*/arg2: 22);
38}
39
40template<typename... Args>
41void variadic(Args&&... args);
42
43template<typename... Args>
44void variadic2(int zzz, Args&&... args);
45
46void templates() {
47 variadic(/*xxx=*/args: 0, /*yyy=*/args: 1);
48 variadic2(/*zzU=*/zzz: 0, /*xxx=*/args: 1, /*yyy=*/args: 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
55void qqq(bool aaa);
56void 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
61void f3(bool _with_underscores_);
62void ignores_underscores() {
63 f3(/*With_Underscores=*/with_underscores_: false);
64}
65
66namespace IgnoresImplicit {
67struct S {
68 S(int x);
69 int x;
70};
71
72struct 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
80void k(T arg1);
81
82void mynewtest() {
83 int foo = 3;
84 k(/*arg1=*/S(foo));
85}
86} // namespace IgnoresImplicit
87
88namespace ThisEditDistanceAboveThreshold {
89void f4(int xxx);
90void g() { f4(/*xyz=*/xxx: 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
96namespace OtherEditDistanceAboveThreshold {
97void f5(int xxx, int yyy);
98void g() { f5(/*Zxx=*/xxx: 0, yyy: 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); }
102struct C2 {
103 C2(int xxx, int yyy);
104};
105C2 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
111namespace OtherEditDistanceBelowThreshold {
112void f6(int xxx, int yyy);
113void g() { f6(/*xxy=*/xxx: 0, yyy: 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
120namespace std {
121template <typename T>
122class vector {
123public:
124 void assign(int __n, const T &__val);
125};
126template<typename T>
127void swap(T& __a, T& __b);
128} // namespace std
129namespace ignore_std_functions {
130void test(int a, int b) {
131 std::vector<int> s;
132 // verify the check is not fired on std functions.
133 s.assign(n: 1, /*value=*/val: 2);
134 std::swap(a&: a, /*num=*/b&: b);
135}
136} // namespace ignore_std_functions
137
138namespace regular_header {
139#include "header-with-decl.h"
140void test() {
141 my_header_function(/*not_arg=*/1);
142// CHECK-NOTES: [[@LINE-1]]:22: warning: argument name 'not_arg' in comment does not match parameter name 'arg'
143// CHECK-NOTES: header-with-decl.h:1:29: note: 'arg' declared here
144// CHECK-FIXES: my_header_function(/*not_arg=*/1);
145}
146} // namespace regular_header
147
148namespace system_header {
149#include "system-header-with-decl.h"
150void test() {
151 my_system_header_function(/*not_arg=*/1);
152}
153} // namespace system_header
154
155void testInvalidSlocCxxConstructExpr() {
156 __builtin_va_list __args;
157 // __builtin_va_list has no defination in any source file
158}
159

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/argument-comment.cpp