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
6typedef __SIZE_TYPE__ size_t;
7
8namespace std {
9template <typename T>
10struct 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
23template <typename T>
24struct is_integral;
25
26template <>
27struct is_integral<size_t> {
28 static const bool value = true;
29};
30
31template <bool, typename T = void>
32struct enable_if { };
33
34template <typename T>
35struct enable_if<true, T> {
36 typedef T type;
37};
38}
39
40template <typename T>
41void f(const T *);
42
43#define z (0)
44
45void 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
52void h() {
53 std::string s;
54 f(&((s).operator[](pos: (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[](pos: (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
66template <typename T, typename U,
67 typename = typename std::enable_if<std::is_integral<U>::value>::type>
68void 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
75template void i<unsigned char, size_t>(size_t);
76
77void 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
83void 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
89void 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
95template <typename T>
96void 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
102template <typename T>
103struct container_without_data {
104 using size_type = size_t;
105 T &operator[](size_type);
106 const T &operator[](size_type) const;
107};
108
109template <typename T>
110const 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
115const 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
121std::vector<int> &select(std::vector<int> &u, std::vector<int> &v) {
122 return v;
123}
124
125int *p(std::vector<int> &v1, std::vector<int> &v2) {
126 return &select(u&: *&v1, v&: 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
131int *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
137struct VectorHolder {
138 std::vector<int> v;
139};
140
141int *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

source code of clang-tools-extra/test/clang-tidy/checkers/readability/container-data-pointer.cpp