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 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 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> 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 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 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 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> 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> 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 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 132 std::vector<int> &select(std::vector<int> &u, std::vector<int> &v) { 133 return v; 134 } 135 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 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