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