189a1d03eSRichard // RUN: %check_clang_tidy %s readability-simplify-subscript-expr %t \ 289a1d03eSRichard // RUN: -config="{CheckOptions: \ 3*e8a3ddafSNathan James // RUN: {readability-simplify-subscript-expr.Types: \ 4*e8a3ddafSNathan James // RUN: '::std::basic_string;::std::basic_string_view;MyVector'}}" -- 589a1d03eSRichard 689a1d03eSRichard namespace std { 789a1d03eSRichard 889a1d03eSRichard template <class T> 989a1d03eSRichard class basic_string { 1089a1d03eSRichard public: 1189a1d03eSRichard using size_type = unsigned; 1289a1d03eSRichard using value_type = T; 1389a1d03eSRichard using reference = value_type&; 1489a1d03eSRichard using const_reference = const value_type&; 1589a1d03eSRichard 1689a1d03eSRichard reference operator[](size_type); 1789a1d03eSRichard const_reference operator[](size_type) const; 1889a1d03eSRichard T* data(); 1989a1d03eSRichard const T* data() const; 2089a1d03eSRichard }; 2189a1d03eSRichard 2289a1d03eSRichard using string = basic_string<char>; 2389a1d03eSRichard 2489a1d03eSRichard template <class T> 2589a1d03eSRichard class basic_string_view { 2689a1d03eSRichard public: 2789a1d03eSRichard using size_type = unsigned; 2889a1d03eSRichard using const_reference = const T&; 2989a1d03eSRichard using const_pointer = const T*; 3089a1d03eSRichard 3189a1d03eSRichard constexpr const_reference operator[](size_type) const; 3289a1d03eSRichard constexpr const_pointer data() const noexcept; 3389a1d03eSRichard }; 3489a1d03eSRichard 3589a1d03eSRichard using string_view = basic_string_view<char>; 3689a1d03eSRichard 3789a1d03eSRichard } 3889a1d03eSRichard 3989a1d03eSRichard template <class T> 4089a1d03eSRichard class MyVector { 4189a1d03eSRichard public: 4289a1d03eSRichard using size_type = unsigned; 4389a1d03eSRichard using const_reference = const T&; 4489a1d03eSRichard using const_pointer = const T*; 4589a1d03eSRichard 4689a1d03eSRichard const_reference operator[](size_type) const; 4789a1d03eSRichard const T* data() const noexcept; 4889a1d03eSRichard }; 4989a1d03eSRichard 5089a1d03eSRichard #define DO(x) do { x; } while (false) 5189a1d03eSRichard #define ACCESS(x) (x) 5289a1d03eSRichard #define GET(x, i) (x).data()[i] 5389a1d03eSRichard 5489a1d03eSRichard template <class T> 5589a1d03eSRichard class Foo { 5689a1d03eSRichard public: bar(int i)5789a1d03eSRichard char bar(int i) { 5889a1d03eSRichard return x.data()[i]; 5989a1d03eSRichard } 6089a1d03eSRichard private: 6189a1d03eSRichard T x; 6289a1d03eSRichard }; 6389a1d03eSRichard f(int i)6489a1d03eSRichardvoid f(int i) { 6589a1d03eSRichard MyVector<int> v; 6689a1d03eSRichard int x = v.data()[i]; 6789a1d03eSRichard // 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] 6889a1d03eSRichard // CHECK-FIXES: int x = v[i]; 6989a1d03eSRichard 7089a1d03eSRichard std::string s; 7189a1d03eSRichard char c1 = s.data()[i]; 7289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: accessing an element 7389a1d03eSRichard // CHECK-FIXES: char c1 = s[i]; 7489a1d03eSRichard 7589a1d03eSRichard std::string_view sv; 7689a1d03eSRichard char c2 = sv.data()[i]; 7789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: accessing an element 7889a1d03eSRichard // CHECK-FIXES: char c2 = sv[i]; 7989a1d03eSRichard 8089a1d03eSRichard std::string* ps = &s; 8189a1d03eSRichard char c3 = ps->data()[i]; 8289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: accessing an element 8389a1d03eSRichard // CHECK-FIXES: char c3 = (*ps)[i]; 8489a1d03eSRichard 8589a1d03eSRichard char c4 = (*ps).data()[i]; 8689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: accessing an element 8789a1d03eSRichard // CHECK-FIXES: char c4 = (*ps)[i]; 8889a1d03eSRichard 8989a1d03eSRichard DO(char c5 = s.data()[i]); 9089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: accessing an element 9189a1d03eSRichard // CHECK-FIXES: DO(char c5 = s[i]); 9289a1d03eSRichard 9389a1d03eSRichard char c6 = ACCESS(s).data()[i]; 9489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: accessing an element 9589a1d03eSRichard // CHECK-FIXES: char c6 = ACCESS(s)[i]; 9689a1d03eSRichard 9789a1d03eSRichard char c7 = ACCESS(s.data())[i]; 9889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: accessing an element 9989a1d03eSRichard // CHECK-FIXES: char c7 = ACCESS(s)[i]; 10089a1d03eSRichard 10189a1d03eSRichard char c8 = ACCESS(s.data()[i]); 10289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: accessing an element 10389a1d03eSRichard // CHECK-FIXES: char c8 = ACCESS(s[i]); 10489a1d03eSRichard 10589a1d03eSRichard char c9 = GET(s, i); 10689a1d03eSRichard 10789a1d03eSRichard char c10 = Foo<std::string>{}.bar(i); 10889a1d03eSRichard } 109