1 // RUN: %check_clang_tidy %s readability-simplify-subscript-expr %t \ 2 // RUN: -config="{CheckOptions: \ 3 // RUN: [{key: readability-simplify-subscript-expr.Types, \ 4 // RUN: value: '::std::basic_string;::std::basic_string_view;MyVector'}]}" -- 5 6 namespace std { 7 8 template <class T> 9 class basic_string { 10 public: 11 using size_type = unsigned; 12 using value_type = T; 13 using reference = value_type&; 14 using const_reference = const value_type&; 15 16 reference operator[](size_type); 17 const_reference operator[](size_type) const; 18 T* data(); 19 const T* data() const; 20 }; 21 22 using string = basic_string<char>; 23 24 template <class T> 25 class basic_string_view { 26 public: 27 using size_type = unsigned; 28 using const_reference = const T&; 29 using const_pointer = const T*; 30 31 constexpr const_reference operator[](size_type) const; 32 constexpr const_pointer data() const noexcept; 33 }; 34 35 using string_view = basic_string_view<char>; 36 37 } 38 39 template <class T> 40 class MyVector { 41 public: 42 using size_type = unsigned; 43 using const_reference = const T&; 44 using const_pointer = const T*; 45 46 const_reference operator[](size_type) const; 47 const T* data() const noexcept; 48 }; 49 50 #define DO(x) do { x; } while (false) 51 #define ACCESS(x) (x) 52 #define GET(x, i) (x).data()[i] 53 54 template <class T> 55 class Foo { 56 public: bar(int i)57 char bar(int i) { 58 return x.data()[i]; 59 } 60 private: 61 T x; 62 }; 63 f(int i)64void f(int i) { 65 MyVector<int> v; 66 int x = v.data()[i]; 67 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: accessing an element of the container does not require a call to 'data()'; did you mean to use 'operator[]'? [readability-simplify-subscript-expr] 68 // CHECK-FIXES: int x = v[i]; 69 70 std::string s; 71 char c1 = s.data()[i]; 72 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: accessing an element 73 // CHECK-FIXES: char c1 = s[i]; 74 75 std::string_view sv; 76 char c2 = sv.data()[i]; 77 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: accessing an element 78 // CHECK-FIXES: char c2 = sv[i]; 79 80 std::string* ps = &s; 81 char c3 = ps->data()[i]; 82 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: accessing an element 83 // CHECK-FIXES: char c3 = (*ps)[i]; 84 85 char c4 = (*ps).data()[i]; 86 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: accessing an element 87 // CHECK-FIXES: char c4 = (*ps)[i]; 88 89 DO(char c5 = s.data()[i]); 90 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: accessing an element 91 // CHECK-FIXES: DO(char c5 = s[i]); 92 93 char c6 = ACCESS(s).data()[i]; 94 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: accessing an element 95 // CHECK-FIXES: char c6 = ACCESS(s)[i]; 96 97 char c7 = ACCESS(s.data())[i]; 98 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: accessing an element 99 // CHECK-FIXES: char c7 = ACCESS(s)[i]; 100 101 char c8 = ACCESS(s.data()[i]); 102 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: accessing an element 103 // CHECK-FIXES: char c8 = ACCESS(s[i]); 104 105 char c9 = GET(s, i); 106 107 char c10 = Foo<std::string>{}.bar(i); 108 } 109