| 1 | // RUN: %check_clang_tidy %s bugprone-sizeof-container %t -- -- -target x86_64-unknown-unknown |
| 2 | |
| 3 | namespace std { |
| 4 | |
| 5 | typedef unsigned int size_t; |
| 6 | |
| 7 | template <typename T> |
| 8 | struct basic_string { |
| 9 | size_t size() const; |
| 10 | }; |
| 11 | |
| 12 | template <typename T> |
| 13 | basic_string<T> operator+(const basic_string<T> &, const T *); |
| 14 | |
| 15 | typedef basic_string<char> string; |
| 16 | |
| 17 | template <typename T> |
| 18 | struct vector { |
| 19 | size_t size() const; |
| 20 | }; |
| 21 | |
| 22 | // std::bitset<> is not a container. sizeof() is reasonable for it. |
| 23 | template <size_t N> |
| 24 | struct bitset { |
| 25 | size_t size() const; |
| 26 | }; |
| 27 | |
| 28 | // std::array<> is, well, an array. sizeof() is reasonable for it. |
| 29 | template <typename T, size_t N> |
| 30 | struct array { |
| 31 | size_t size() const; |
| 32 | }; |
| 33 | |
| 34 | class fake_container1 { |
| 35 | size_t size() const; // non-public |
| 36 | }; |
| 37 | |
| 38 | struct fake_container2 { |
| 39 | size_t size(); // non-const |
| 40 | }; |
| 41 | |
| 42 | } |
| 43 | |
| 44 | using std::size_t; |
| 45 | |
| 46 | #define ARRAYSIZE(a) \ |
| 47 | ((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) |
| 48 | |
| 49 | #define ARRAYSIZE2(a) \ |
| 50 | (((sizeof(a)) / (sizeof(*(a)))) / static_cast<size_t>(!((sizeof(a)) % (sizeof(*(a)))))) |
| 51 | |
| 52 | struct string { |
| 53 | std::size_t size() const; |
| 54 | }; |
| 55 | |
| 56 | template<typename T> |
| 57 | void g(T t) { |
| 58 | (void)sizeof(t); |
| 59 | } |
| 60 | |
| 61 | void f() { |
| 62 | string s1; |
| 63 | std::string s2; |
| 64 | std::vector<int> v; |
| 65 | |
| 66 | int a = 42 + sizeof(s1); |
| 67 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: sizeof() doesn't return the size of the container; did you mean .size()? [bugprone-sizeof-container] |
| 68 | a = 123 * sizeof(s2); |
| 69 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: sizeof() doesn't return the size |
| 70 | a = 45 + sizeof(s2 + "asdf" ); |
| 71 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: sizeof() doesn't return the size |
| 72 | a = sizeof(v); |
| 73 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: sizeof() doesn't return the size |
| 74 | a = sizeof(std::vector<int>{}); |
| 75 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: sizeof() doesn't return the size |
| 76 | |
| 77 | a = sizeof(a); |
| 78 | a = sizeof(int); |
| 79 | a = sizeof(std::string); |
| 80 | a = sizeof(std::vector<int>); |
| 81 | |
| 82 | g(t: s1); |
| 83 | g(t: s2); |
| 84 | g(t: v); |
| 85 | |
| 86 | std::fake_container1 fake1; |
| 87 | std::fake_container2 fake2; |
| 88 | std::bitset<7> std_bitset; |
| 89 | std::array<int, 3> std_array; |
| 90 | |
| 91 | a = sizeof(fake1); |
| 92 | a = sizeof(fake2); |
| 93 | a = sizeof(std_bitset); |
| 94 | a = sizeof(std_array); |
| 95 | |
| 96 | |
| 97 | std::string arr[3]; |
| 98 | a = ARRAYSIZE(arr); |
| 99 | a = ARRAYSIZE2(arr); |
| 100 | a = sizeof(arr) / sizeof(arr[0]); |
| 101 | |
| 102 | (void)a; |
| 103 | } |
| 104 | |