brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.6 KiB · 3987526 Raw
359 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-narrowing-conversions %t \2// RUN: -config="{CheckOptions: { \3// RUN:   bugprone-narrowing-conversions.WarnOnFloatingPointNarrowingConversion: false}}" \4// RUN: -- -target x86_64-unknown-linux -fsigned-char5 6float ceil(float);7namespace std {8double ceil(double);9long double floor(long double);10} // namespace std11 12namespace floats {13 14struct ConvertsToFloat {15  operator float() const { return 0.5f; }16};17 18float operator"" _float(unsigned long long);19 20void narrow_fp_to_int_not_ok(double d) {21  int i = 0;22  i = d;23  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [bugprone-narrowing-conversions]24  i = 0.5f;25  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions]26  i = static_cast<float>(d);27  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [bugprone-narrowing-conversions]28  i = ConvertsToFloat();29  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [bugprone-narrowing-conversions]30  i = 15_float;31  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [bugprone-narrowing-conversions]32  i += d;33  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [bugprone-narrowing-conversions]34  i += 0.5;35  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [bugprone-narrowing-conversions]36  i += 0.5f;37  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions]38  i *= 0.5f;39  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions]40  i /= 0.5f;41  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions]42  i += (double)0.5f;43  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [bugprone-narrowing-conversions]44  i += 2.0;45  i += 2.0f;46}47 48double operator"" _double(unsigned long long);49 50float narrow_double_to_float_return() {51  return 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.52}53 54void narrow_double_to_float_ok(double d) {55  float f;56  f = d;57  f = 15_double;58}59 60void narrow_fp_constants() {61  float f;62  f = 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.63 64  f = __builtin_huge_valf();  // max float is not narrowing.65  f = -__builtin_huge_valf(); // -max float is not narrowing.66  f = __builtin_inff();       // float infinity is not narrowing.67  f = __builtin_nanf("0");    // float NaN is not narrowing.68 69  f = __builtin_huge_val();  // max double is not within-range of float.70  f = -__builtin_huge_val(); // -max double is not within-range of float.71  f = __builtin_inf();       // double infinity is not within-range of float.72  f = __builtin_nan("0");    // double NaN is not narrowing.73}74 75void narrow_double_to_float_not_ok_binary_ops(double d) {76  float f;77  f += 0.5;          // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.78  f += 2.0;          // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.79  f *= 0.5;          // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.80  f /= 0.5;          // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.81  f += (double)0.5f; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.82  f += d;            // We do not warn about floating point narrowing by default.83}84 85void narrow_fp_constant_to_bool_not_ok() {86  bool b1 = 1.0;87  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'double' to 'bool' [bugprone-narrowing-conversions]88  bool b2 = 1.0f;89  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'float' to 'bool' [bugprone-narrowing-conversions]90}91 92void narrow_integer_to_floating() {93  {94    long long ll; // 64 bits95    float f = ll; // doesn't fit in 24 bits96    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'long long' to 'float' [bugprone-narrowing-conversions]97    double d = ll; // doesn't fit in 53 bits.98    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: narrowing conversion from 'long long' to 'double' [bugprone-narrowing-conversions]99  }100  {101    int i;       // 32 bits102    float f = i; // doesn't fit in 24 bits103    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [bugprone-narrowing-conversions]104    double d = i; // fits in 53 bits.105  }106  {107    short n1, n2;108    float f = n1 + n2; // 'n1 + n2' is of type 'int' because of integer rules109    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [bugprone-narrowing-conversions]110  }111  {112    short s;      // 16 bits113    float f = s;  // fits in 24 bits114    double d = s; // fits in 53 bits.115  }116}117 118void narrow_integer_to_unsigned_integer_is_ok() {119  char c;120  short s;121  int i;122  long l;123  long long ll;124 125  unsigned char uc;126  unsigned short us;127  unsigned int ui;128  unsigned long ul;129  unsigned long long ull;130 131  ui = c;132  uc = s;133  uc = i;134  uc = l;135  uc = ll;136 137  uc = uc;138  uc = us;139  uc = ui;140  uc = ul;141  uc = ull;142}143 144void narrow_integer_to_signed_integer_is_not_ok() {145  char c;146  short s;147  int i;148  long l;149  long long ll;150 151  unsigned char uc;152  unsigned short us;153  unsigned int ui;154  unsigned long ul;155  unsigned long long ull;156 157  c = c;158  c = s;159  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'short' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]160  c = i;161  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]162  c = l;163  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]164  c = ll;165  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]166 167  c = uc;168  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned char' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]169  c = us;170  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned short' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]171  c = ui;172  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]173  c = ul;174  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]175  c = ull;176  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]177 178  i = c;179  i = s;180  i = i;181  i = l;182  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]183  i = ll;184  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]185 186  i = uc;187  i = us;188  i = ui;189  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]190  i = ul;191  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]192  i = ull;193  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]194 195  ll = c;196  ll = s;197  ll = i;198  ll = l;199  ll = ll;200 201  ll = uc;202  ll = us;203  ll = ui;204  ll = ul;205  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions]206  ll = ull;207  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions]208}209 210void narrow_constant_to_unsigned_integer_is_ok() {211  unsigned char uc1 = 0;212  unsigned char uc2 = 255;213  unsigned char uc3 = -1;  // unsigned dst type is well defined.214  unsigned char uc4 = 256; // unsigned dst type is well defined.215  unsigned short us1 = 0;216  unsigned short us2 = 65535;217  unsigned short us3 = -1;    // unsigned dst type is well defined.218  unsigned short us4 = 65536; // unsigned dst type is well defined.219}220 221void narrow_constant_to_signed_integer_is_not_ok() {222  char c1 = -128;223  char c2 = 127;224  char c3 = -129;225  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]226  char c4 = 128;227  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]228 229  short s1 = -32768;230  short s2 = 32767;231  short s3 = -32769;232  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value -32769 (0xFFFF7FFF) of type 'int' to signed type 'short' is implementation-defined [bugprone-narrowing-conversions]233  short s4 = 32768;234  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value 32768 (0x00008000) of type 'int' to signed type 'short' is implementation-defined [bugprone-narrowing-conversions]235}236 237void narrow_conditional_operator_contant_to_unsigned_is_ok(bool b) {238  // conversion to unsigned dst type is well defined.239  unsigned char c1 = b ? 1 : 0;240  unsigned char c2 = b ? 1 : 256;241  unsigned char c3 = b ? -1 : 0;242}243 244void narrow_conditional_operator_contant_to_signed_is_not_ok(bool b) {245  char uc1 = b ? 1 : 0;246  char uc2 = b ? 1 : 128;247  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]248  char uc3 = b ? -129 : 0;249  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]250  unsigned long long ysize;251  long long mirror = b ? -1 : ysize - 1;252  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: narrowing conversion from constant value 18446744073709551615 (0xFFFFFFFFFFFFFFFF) of type 'unsigned long long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions]253  // CHECK-MESSAGES: :[[@LINE-2]]:37: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions]254}255 256void narrow_constant_to_floating_point() {257  float f_ok = 1ULL << 24;              // fits in 24 bits mantissa.258  float f_not_ok = (1ULL << 24) + 1ULL; // doesn't fit in 24 bits mantissa.259  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: narrowing conversion from constant value 16777217 of type 'unsigned long long' to 'float' [bugprone-narrowing-conversions]260  double d_ok = 1ULL << 53;              // fits in 53 bits mantissa.261  double d_not_ok = (1ULL << 53) + 1ULL; // doesn't fit in 53 bits mantissa.262  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: narrowing conversion from constant value 9007199254740993 of type 'unsigned long long' to 'double' [bugprone-narrowing-conversions]263}264 265void casting_integer_to_bool_is_ok() {266  int i;267  while (i) {268  }269  for (; i;) {270  }271  if (i) {272  }273}274 275void casting_float_to_bool_is_not_ok() {276  float f;277  while (f) {278    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [bugprone-narrowing-conversions]279  }280  for (; f;) {281    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [bugprone-narrowing-conversions]282  }283  if (f) {284    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'bool' [bugprone-narrowing-conversions]285  }286}287 288void legitimate_comparison_do_not_warn(unsigned long long size) {289  for (int i = 0; i < size; ++i) {290  }291}292 293void ok(double d) {294  int i = 0;295  i = 1;296  i = static_cast<int>(0.5);297  i = static_cast<int>(d);298  i = std::ceil(0.5);299  i = ::std::floor(0.5);300  {301    using std::ceil;302    i = ceil(0.5f);303  }304  i = ceil(0.5f);305}306 307void ok_binary_ops(double d) {308  int i = 0;309  i += 1;310  i += static_cast<int>(0.5);311  i += static_cast<int>(d);312  i += (int)d;313  i += std::ceil(0.5);314  i += ::std::floor(0.5);315  {316    using std::ceil;317    i += ceil(0.5f);318  }319  i += ceil(0.5f);320}321 322// We're bailing out in templates and macros.323template <typename T1, typename T2>324void f(T1 one, T2 two) {325  one += two;326}327 328void template_context() {329  f(1, 2);330  f(1, .5f);331  f(1, .5);332  f(1, .5l);333}334 335#define DERP(i, j) (i += j)336 337void macro_context() {338  int i = 0;339  DERP(i, 2);340  DERP(i, .5f);341  DERP(i, .5);342  DERP(i, .5l);343}344 345// We understand typedefs.346void typedef_context() {347  typedef long long myint64_t;348  int i;349  myint64_t i64;350 351  i64 = i64; // Okay, no conversion.352  i64 = i;   // Okay, no narrowing.353 354  i = i64;355  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'myint64_t' (aka 'long long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]356}357 358} // namespace floats359