204 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-narrowing-conversions %t \2// RUN: -std=c++17 -- -target x86_64-unknown-linux3 4#define CHAR_BITS 85static_assert(sizeof(unsigned int) == 32 / CHAR_BITS);6 7template <typename T, typename U>8struct is_same {9 static constexpr bool value = false;10};11template <typename T>12struct is_same<T, T> {13 static constexpr bool value = true;14};15 16template <typename T, typename U>17static constexpr bool is_same_v = is_same<T, U>::value;18 19struct NoBitfield {20 unsigned int id;21};22struct SmallBitfield {23 unsigned int id : 4;24};25 26struct BigBitfield {27 unsigned int id : 31;28};29struct CompleteBitfield {30 unsigned int id : 32;31};32 33int 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 38void 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 49void 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 60template <typename T>61void take(T);62 63void 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-defined66 take<short>(x.id);67 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'unsigned int' to signed type 'short' is implementation-defined68 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-defined71 take<long>(x.id);72 take<long long>(x.id);73}74 75void 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-defined78 take<short>(x.id);79 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'unsigned int' to signed type 'short' is implementation-defined80 take<unsigned>(x.id);81 take<int>(x.id); // no-warning82 take<long>(x.id);83 take<long long>(x.id);84}85 86void 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-defined89 take<short>(x.id);90 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'unsigned int' to signed type 'short' is implementation-defined91 take<unsigned>(x.id);92 take<int>(x.id); // no-warning93 take<long>(x.id);94 take<long long>(x.id);95}96 97void 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-defined100 take<short>(x.id);101 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'unsigned int' to signed type 'short' is implementation-defined102 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-defined105 take<long>(x.id);106 take<long long>(x.id);107}108 109void 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 130void 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 151void 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 172void 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 193void 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