1 // RUN: %check_clang_tidy %s bugprone-narrowing-conversions %t \ 2 // RUN: -std=c++17 -- -target x86_64-unknown-linux 3 4 #define CHAR_BITS 8 5 static_assert(sizeof(unsigned int) == 32 / CHAR_BITS); 6 7 template <typename T, typename U> 8 struct is_same { 9 static constexpr bool value = false; 10 }; 11 template <typename T> 12 struct is_same<T, T> { 13 static constexpr bool value = true; 14 }; 15 16 template <typename T, typename U> 17 static constexpr bool is_same_v = is_same<T, U>::value; 18 19 struct NoBitfield { 20 unsigned int id; 21 }; 22 struct SmallBitfield { 23 unsigned int id : 4; 24 }; 25 26 struct BigBitfield { 27 unsigned int id : 31; 28 }; 29 struct CompleteBitfield { 30 unsigned int id : 32; 31 }; 32 33 int example_warning(unsigned x) { 34 // CHECK-MESSAGES: :[[@LINE+1]]:10: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions] 35 return x; 36 } 37 38 void test_binary_and(SmallBitfield x) { 39 static_assert(is_same_v<decltype(x.id & 1), int>); 40 static_assert(is_same_v<decltype(x.id & 1u), unsigned>); 41 42 x.id & 1; 43 x.id & 1u; 44 45 1 & x.id; 46 1u & x.id; 47 } 48 49 void test_binary_or(SmallBitfield x) { 50 static_assert(is_same_v<decltype(x.id | 1), int>); 51 static_assert(is_same_v<decltype(x.id | 1u), unsigned>); 52 53 x.id | 1; 54 x.id | 1u; 55 56 1 | x.id; 57 1u | x.id; 58 } 59 60 template <typename T> 61 void take(T); 62 63 void test_parameter_passing(NoBitfield x) { 64 take<char>(x.id); 65 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined 66 take<short>(x.id); 67 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'unsigned int' to signed type 'short' is implementation-defined 68 take<unsigned>(x.id); 69 take<int>(x.id); 70 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined 71 take<long>(x.id); 72 take<long long>(x.id); 73 } 74 75 void test_parameter_passing(SmallBitfield x) { 76 take<char>(x.id); 77 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined 78 take<short>(x.id); 79 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'unsigned int' to signed type 'short' is implementation-defined 80 take<unsigned>(x.id); 81 take<int>(x.id); // no-warning 82 take<long>(x.id); 83 take<long long>(x.id); 84 } 85 86 void test_parameter_passing(BigBitfield x) { 87 take<char>(x.id); 88 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined 89 take<short>(x.id); 90 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'unsigned int' to signed type 'short' is implementation-defined 91 take<unsigned>(x.id); 92 take<int>(x.id); // no-warning 93 take<long>(x.id); 94 take<long long>(x.id); 95 } 96 97 void test_parameter_passing(CompleteBitfield x) { 98 take<char>(x.id); 99 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined 100 take<short>(x.id); 101 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'unsigned int' to signed type 'short' is implementation-defined 102 take<unsigned>(x.id); 103 take<int>(x.id); 104 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined 105 take<long>(x.id); 106 take<long long>(x.id); 107 } 108 109 void test(NoBitfield x) { 110 static_assert(is_same_v<decltype(x.id << 1), unsigned>); 111 static_assert(is_same_v<decltype(x.id << 1u), unsigned>); 112 static_assert(is_same_v<decltype(x.id + 1), unsigned>); 113 static_assert(is_same_v<decltype(x.id + 1u), unsigned>); 114 115 x.id << 1; 116 x.id << 1u; 117 x.id >> 1; 118 x.id >> 1u; 119 x.id + 1; 120 x.id + 1u; 121 122 1 << x.id; 123 1u << x.id; 124 1 >> x.id; 125 1u >> x.id; 126 1 + x.id; 127 1u + x.id; 128 } 129 130 void test(SmallBitfield x) { 131 static_assert(is_same_v<decltype(x.id << 1), int>); 132 static_assert(is_same_v<decltype(x.id << 1u), int>); 133 134 x.id << 1; 135 x.id << 1u; 136 x.id >> 1; 137 x.id >> 1u; 138 139 x.id + 1; 140 x.id + 1u; 141 142 1 << x.id; 143 1u << x.id; 144 1 >> x.id; 145 1u >> x.id; 146 147 1 + x.id; 148 1u + x.id; 149 } 150 151 void test(BigBitfield x) { 152 static_assert(is_same_v<decltype(x.id << 1), int>); 153 static_assert(is_same_v<decltype(x.id << 1u), int>); 154 155 x.id << 1; 156 x.id << 1u; 157 x.id >> 1; 158 x.id >> 1u; 159 160 x.id + 1; 161 x.id + 1u; 162 163 1 << x.id; 164 1u << x.id; 165 1 >> x.id; 166 1u >> x.id; 167 168 1 + x.id; 169 1u + x.id; 170 } 171 172 void test(CompleteBitfield x) { 173 static_assert(is_same_v<decltype(x.id << 1), unsigned>); 174 static_assert(is_same_v<decltype(x.id << 1u), unsigned>); 175 176 x.id << 1; 177 x.id << 1u; 178 x.id >> 1; 179 x.id >> 1u; 180 181 x.id + 1; 182 x.id + 1u; 183 184 1 << x.id; 185 1u << x.id; 186 1 >> x.id; 187 1u >> x.id; 188 189 1 + x.id; 190 1u + x.id; 191 } 192 193 void test_parens(SmallBitfield x) { 194 static_assert(is_same_v<decltype(x.id << (2)), int>); 195 static_assert(is_same_v<decltype(((x.id)) << (2)), int>); 196 x.id << (2); 197 ((x.id)) << (2); 198 199 static_assert(is_same_v<decltype((2) << x.id), int>); 200 static_assert(is_same_v<decltype((2) << ((x.id))), int>); 201 (2) << x.id; 202 (2) << ((x.id)); 203 } 204