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