xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/container-data-pointer.cpp (revision 1af159e98c23a293c103e1f548866488126ed6f6)
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