// RUN: %check_clang_tidy -check-suffixes=,CLASSIC %s readability-container-data-pointer %t -- -- -isystem %clang_tidy_headers -fno-delayed-template-parsing // 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 #include typedef __SIZE_TYPE__ size_t; namespace std { template struct vector { using size_type = size_t; vector(); explicit vector(size_type); T *data(); const T *data() const; T &operator[](size_type); const T &operator[](size_type) const; }; template struct is_integral; template <> struct is_integral { static const bool value = true; }; template struct enable_if { }; template struct enable_if { typedef T type; }; } template void f(const T *); #define z (0) void g(size_t s) { std::vector b(s); f(&((b)[(z)])); // 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] // CHECK-FIXES: {{^ }}f(b.data());{{$}} } void h() { std::string s; f(&((s).operator[]((z)))); // 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] // CHECK-FIXES-CLASSIC: {{^ }}f(s.data());{{$}} // 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] std::wstring w; f(&((&(w))->operator[]((z)))); // 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] // CHECK-FIXES-CLASSIC: {{^ }}f(w.data());{{$}} // 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] } template ::value>::type> void i(U s) { std::vector b(s); f(&b[0]); // 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] // CHECK-FIXES: {{^ }}f(b.data());{{$}} } template void i(size_t); void j(std::vector * const v) { f(&(*v)[0]); // 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] // CHECK-FIXES: {{^ }}f(v->data());{{$}} } void k(const std::vector &v) { f(&v[0]); // 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] // CHECK-FIXES: {{^ }}f(v.data());{{$}} } void l() { unsigned char b[32]; f(&b[0]); // 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] } template void m(const std::vector &v) { return &v[0]; // 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] // CHECK-FIXES: {{^ }}return v.data();{{$}} } template struct container_without_data { using size_type = size_t; T &operator[](size_type); const T &operator[](size_type) const; }; template const T *n(const container_without_data &c) { // c has no "data" member function, so there should not be a warning here: return &c[0]; } const int *o(const std::vector>> &v, const size_t idx1, const size_t idx2) { return &v[idx1][idx2][0]; // 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] // CHECK-FIXES: {{^ }}return v[idx1][idx2].data();{{$}} } std::vector &select(std::vector &u, std::vector &v) { return v; } int *p(std::vector &v1, std::vector &v2) { return &select(*&v1, v2)[0]; // 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] // CHECK-FIXES: {{^ }}return select(*&v1, v2).data();{{$}} } int *q(std::vector ***v) { return &(***v)[0]; // 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] // CHECK-FIXES: {{^ }}return (**v)->data();{{$}} } struct VectorHolder { std::vector v; }; int *r() { VectorHolder holder; return &holder.v[0]; // 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] // CHECK-FIXES: {{^ }}return holder.v.data();{{$}} }