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