1 // RUN: %check_clang_tidy -check-suffixes=,CLASSIC %s readability-container-data-pointer %t -- -- -isystem %clang_tidy_headers -fno-delayed-template-parsing
2 // RUN: %check_clang_tidy -check-suffixes=,WITH-CONFIG %s readability-container-data-pointer %t -- -config="{CheckOptions: {readability-container-data-pointer.IgnoredContainers: '::std::basic_string'}}" -- -isystem %clang_tidy_headers -fno-delayed-template-parsing
3
4 #include <string>
5
6 typedef __SIZE_TYPE__ size_t;
7
8 namespace std {
9 template <typename T>
10 struct vector {
11 using size_type = size_t;
12
13 vector();
14 explicit vector(size_type);
15
16 T *data();
17 const T *data() const;
18
19 T &operator[](size_type);
20 const T &operator[](size_type) const;
21 };
22
23 template <typename T>
24 struct is_integral;
25
26 template <>
27 struct is_integral<size_t> {
28 static const bool value = true;
29 };
30
31 template <bool, typename T = void>
32 struct enable_if { };
33
34 template <typename T>
35 struct enable_if<true, T> {
36 typedef T type;
37 };
38 }
39
40 template <typename T>
41 void f(const T *);
42
43 #define z (0)
44
g(size_t s)45 void g(size_t s) {
46 std::vector<unsigned char> b(s);
47 f(&((b)[(z)]));
48 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
49 // CHECK-FIXES: {{^ }}f(b.data());{{$}}
50 }
51
h()52 void h() {
53 std::string s;
54 f(&((s).operator[]((z))));
55 // CHECK-MESSAGES-CLASSIC: :[[@LINE-1]]:5: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
56 // CHECK-FIXES-CLASSIC: {{^ }}f(s.data());{{$}}
57 // CHECK-MESSAGES-WITH-CONFIG-NOT: :[[@LINE-3]]:5: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
58
59 std::wstring w;
60 f(&((&(w))->operator[]((z))));
61 // CHECK-MESSAGES-CLASSIC: :[[@LINE-1]]:5: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
62 // CHECK-FIXES-CLASSIC: {{^ }}f(w.data());{{$}}
63 // CHECK-MESSAGES-WITH-CONFIG-NOT: :[[@LINE-3]]:5: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
64 }
65
66 template <typename T, typename U,
67 typename = typename std::enable_if<std::is_integral<U>::value>::type>
i(U s)68 void i(U s) {
69 std::vector<T> b(s);
70 f(&b[0]);
71 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
72 // CHECK-FIXES: {{^ }}f(b.data());{{$}}
73 }
74
75 template void i<unsigned char, size_t>(size_t);
76
j(std::vector<unsigned char> * const v)77 void j(std::vector<unsigned char> * const v) {
78 f(&(*v)[0]);
79 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
80 // CHECK-FIXES: {{^ }}f(v->data());{{$}}
81 }
82
k(const std::vector<unsigned char> & v)83 void k(const std::vector<unsigned char> &v) {
84 f(&v[0]);
85 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
86 // CHECK-FIXES: {{^ }}f(v.data());{{$}}
87 }
88
l()89 void l() {
90 unsigned char b[32];
91 f(&b[0]);
92 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:5: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
93 }
94
95 template <typename T>
m(const std::vector<T> & v)96 void m(const std::vector<T> &v) {
97 return &v[0];
98 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
99 // CHECK-FIXES: {{^ }}return v.data();{{$}}
100 }
101
102 template <typename T>
103 struct container_without_data {
104 using size_type = size_t;
105 T &operator[](size_type);
106 const T &operator[](size_type) const;
107 };
108
109 template <typename T>
n(const container_without_data<T> & c)110 const T *n(const container_without_data<T> &c) {
111 // c has no "data" member function, so there should not be a warning here:
112 return &c[0];
113 }
114
o(const std::vector<std::vector<std::vector<int>>> & v,const size_t idx1,const size_t idx2)115 const int *o(const std::vector<std::vector<std::vector<int>>> &v, const size_t idx1, const size_t idx2) {
116 return &v[idx1][idx2][0];
117 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
118 // CHECK-FIXES: {{^ }}return v[idx1][idx2].data();{{$}}
119 }
120
select(std::vector<int> & u,std::vector<int> & v)121 std::vector<int> &select(std::vector<int> &u, std::vector<int> &v) {
122 return v;
123 }
124
p(std::vector<int> & v1,std::vector<int> & v2)125 int *p(std::vector<int> &v1, std::vector<int> &v2) {
126 return &select(*&v1, v2)[0];
127 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
128 // CHECK-FIXES: {{^ }}return select(*&v1, v2).data();{{$}}
129 }
130
q(std::vector<int> *** v)131 int *q(std::vector<int> ***v) {
132 return &(***v)[0];
133 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
134 // CHECK-FIXES: {{^ }}return (**v)->data();{{$}}
135 }
136
137 struct VectorHolder {
138 std::vector<int> v;
139 };
140
r()141 int *r() {
142 VectorHolder holder;
143 return &holder.v[0];
144 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]
145 // CHECK-FIXES: {{^ }}return holder.v.data();{{$}}
146 }
147