brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.3 KiB · 113150b Raw
404 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-too-small-loop-variable %t -- \2// RUN:   -config="{CheckOptions: \3// RUN:             {bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit: 1024}}" \4// RUN:   -- --target=x86_64-linux5 6long size() { return 294967296l; }7 8////////////////////////////////////////////////////////////////////////////////9/// Test cases correctly caught by bugprone-too-small-loop-variable.10 11void voidBadForLoop() {12  for (int i = 0; i < size(); ++i) {13    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]14  }15}16 17void voidBadForLoop2() {18  for (int i = 0; i < size() + 10; ++i) {19    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]20  }21}22 23void voidBadForLoop3() {24  for (int i = 0; i <= size() - 1; ++i) {25    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]26  }27}28 29void voidBadForLoop4() {30  for (int i = 0; size() > i; ++i) {31    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]32  }33}34 35void voidBadForLoop5() {36  for (int i = 0; size() - 1 >= i; ++i) {37    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]38  }39}40 41void voidBadForLoop6() {42  int i = 0;43  for (; i < size(); ++i) {44    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]45  }46}47 48void voidBadForLoop7() {49    struct Int  {50        int value;51    } i;52 53  for (i.value = 0; i.value < size(); ++i.value) {54  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]55  }56}57 58void voidForLoopUnsignedBound() {59  unsigned size = 3147483647;60  for (int i = 0; i < size; ++i) {61    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: loop variable has narrower type 'int' than iteration's upper bound 'unsigned int' [bugprone-too-small-loop-variable]62  }63}64 65// The iteration's upper bound has a template dependent value.66template <long size>67void doSomething() {68  for (short i = 0; i < size; ++i) {69    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]70  }71}72 73// The iteration's upper bound has a template dependent type.74template <class T>75void doSomething() {76  for (T i = 0; i < size(); ++i) {77    // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: loop variable has narrower type 'short' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]78  }79}80 81void voidForLoopInstantiation() {82  // This line does not trigger the warning.83  doSomething<long>();84  // This one triggers the warning.85  doSomething<short>();86}87 88// A suspicious function used in a macro.89#define SUSPICIOUS_SIZE (size())90void voidBadForLoopWithMacroBound() {91  for (short i = 0; i < SUSPICIOUS_SIZE; ++i) {92    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]93  }94}95 96unsigned int getVal() {97    return 300;98}99 100// The iteration's upper bound has a function declaration.101void voidBadForLoop8() {102  const unsigned int l = getVal();103  for (unsigned char i = 0; i < l; ++i) {104    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: loop variable has narrower type 'unsigned char' than iteration's upper bound 'const unsigned int' [bugprone-too-small-loop-variable]105  }106}107 108////////////////////////////////////////////////////////////////////////////////109/// Correct loops: we should not warn here.110 111// A simple use case when both expressions have the same type.112void voidGoodForLoop() {113  for (long i = 0; i < size(); ++i) { // no warning114  }115}116 117// Other use case where both expressions have the same type,118// but short expressions are converted to int by the compare operator.119void voidGoodForLoop2() {120  short loopCond = 10;121  for (short i = 0; i < loopCond; ++i) { // no warning122  }123}124 125// Because of the integer literal, the iteration's upper bound is int, but we suppress the warning here.126void voidForLoopShortPlusLiteral() {127  short size = 30000;128  for (short i = 0; i <= (size - 1); ++i) { // no warning129  }130}131 132// Addition of two short variables results in an int value, but we suppress this to avoid false positives.133void voidForLoopShortPlusShort() {134  short size = 256;135  short increment = 14;136  for (short i = 0; i < size + increment; ++i) { // no warning137  }138}139 140// In this test case we have different integer types, but here the loop variable has the bigger type.141// The iteration's bound is cast implicitly, not the loop variable.142void voidForLoopBoundImplicitCast() {143  short start = 256;144  short end = 14;145  for (int i = start; i >= end; --i) { // no warning146  }147}148 149// Range based loop and other iterator based loops are ignored by this check.150void voidRangeBasedForLoop() {151  int array[] = {1, 2, 3, 4, 5};152  for (const int &i : array) { // no warning153  }154}155 156////////////////////////////////////////////////////////////////////////////////157/// Future possibilites to improve the check.158 159// False positive: because of the int literal, iteration's upper bound has int type.160void voidForLoopFalsePositive() {161  short size = 30000;162  bool cond = false;163  for (short i = 0; i < (cond ? 0 : size); ++i) {164    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'int' [bugprone-too-small-loop-variable]165  }166}167 168void voidForLoopFalsePositive2() {169  short size = 30000;170  bool cond = false;171  for (short i = 0; i < (!cond ? size : 0); ++i) {172    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'int' [bugprone-too-small-loop-variable]173  }174}175 176// False positive: The loop bound expression contains nested binary operators.177void voidForLoopFalsePositive3() {178  short number = 30000;179  for (short i = 0; i < ((number & 0x7f) + 1); ++i) {180    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'int' [bugprone-too-small-loop-variable]181  }182}183 184// TODO: handle while loop.185void voidBadWhileLoop() {186  short i = 0;187  while (i < size()) { // missing warning188    ++i;189  }190}191 192// TODO: handle do-while loop.193void voidBadDoWhileLoop() {194  short i = 0;195  do {196    ++i;197  } while (i < size()); // missing warning198}199 200// TODO: handle complex loop conditions.201void voidComplexForCond() {202  bool additionalCond = true;203  for (int i = 0; i < size() && additionalCond; ++i) { // missing warning204  }205}206 207////////////////////////////////////////////////////////////////////////////////208/// Suspicious test cases ingored by this check.209 210// Test case with a reverse iteration.211// This is caught by -Wimplicit-int-conversion.212void voidReverseForLoop() {213  for (short i = size() - 1; i >= 0; --i) { // no warning214  }215}216 217// Macro defined literals are used inside the loop condition.218#define SIZE 125219#define SIZE2 (SIZE + 1)220void voidForLoopWithMacroBound() {221  for (short i = 0; i < SIZE2; ++i) { // no warning222  }223}224 225// A suspicious loop is not caught if the iteration's upper bound is a literal.226void voidForLoopWithLiteralBound() {227  for (short i = 0; i < 125; ++i) { // no warning228  }229}230 231// The used literal leads to an infinite loop.232// This is caught by -Wtautological-constant-out-of-range-compare.233void voidForLoopWithBigLiteralBound() {234  for (short i = 0; i < 294967296l; ++i) { // no warning235  }236}237 238enum eSizeType {239  START,240  Y,241  END242};243 244// A suspicious loop is not caught if the iteration's upper bound is an enum value.245void voidForLoopWithEnumBound() {246  for (short i = eSizeType::START; i < eSizeType::END; ++i) { // no warning247  }248}249 250enum eSizeType2 : long {251  START2 = 294967296l,252  Y2,253  END2254};255 256// The used enum value leads to an infinite loop.257// This is caught by -Wtautological-constant-out-of-range-compare.258void voidForLoopWithBigEnumBound() {259  for (short i = eSizeType2::START2; i < eSizeType2::END2; ++i) { // no warning260  }261}262 263// A suspicious loop is not caught if the iteration's upper bound is a constant variable.264void voidForLoopWithConstBound() {265  const long size = 252l;266  for (short i = 0; i < size; ++i) { // no warning267  }268}269 270// The used constant variable leads to an infinite loop.271// This is caught by -Wtautological-constant-out-of-range-compare.272void voidForLoopWithBigConstBound() {273  const long size = 294967296l;274  for (short i = 0; i < size; ++i) { // no warning275  }276}277 278// Should detect proper size of upper bound bitfield279void voidForLoopWithBitfieldOnUpperBound() {280  struct StructWithBitField {281      unsigned bitfield : 5;282  } value = {};283 284  for(unsigned char i = 0U; i < value.bitfield; ++i) { // no warning285  }286}287 288// Should detect proper size of loop variable bitfield289void voidForLoopWithBitfieldOnLoopVar() {290  struct StructWithBitField {291      unsigned bitfield : 9;292  } value = {};293 294  unsigned char upperLimit = 100U;295 296  for(value.bitfield = 0U; value.bitfield < upperLimit; ++value.bitfield) {297  }298}299 300// Should detect proper size of loop variable and upper bound301void voidForLoopWithBitfieldOnLoopVarAndUpperBound() {302  struct StructWithBitField {303      unsigned var : 5, limit : 4;304  } value = {};305 306  for(value.var = 0U; value.var < value.limit; ++value.var) {307  }308}309 310// Should detect proper size of loop variable and upper bound on integers311void voidForLoopWithBitfieldOnLoopVarAndUpperBoundOnInt() {312  struct StructWithBitField {313      unsigned var : 5;314      int limit : 6;315  } value = {};316 317  for(value.var = 0U; value.var < value.limit; ++value.var) {318  }319}320 321void badForLoopWithBitfieldOnUpperBound() {322  struct StructWithBitField {323      unsigned bitfield : 9;324  } value = {};325 326  for(unsigned char i = 0U; i < value.bitfield; ++i) {327  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: loop variable has narrower type 'unsigned char' than iteration's upper bound 'unsigned int:9' [bugprone-too-small-loop-variable]328  }329}330 331void badForLoopWithBitfieldOnLoopVar() {332  struct StructWithBitField {333      unsigned bitfield : 7;334  } value = {};335 336  unsigned char upperLimit = 100U;337 338  for(value.bitfield = 0U; value.bitfield < upperLimit; ++value.bitfield) {339  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: loop variable has narrower type 'unsigned int:7' than iteration's upper bound 'unsigned char' [bugprone-too-small-loop-variable]340  }341}342 343void badForLoopWithBitfieldOnLoopVarAndUpperBound() {344  struct StructWithBitField {345      unsigned var : 5, limit : 6;346  } value = {};347 348  for(value.var = 0U; value.var < value.limit; ++value.var) {349  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: loop variable has narrower type 'unsigned int:5' than iteration's upper bound 'unsigned int:6' [bugprone-too-small-loop-variable]350  }351}352 353void badForLoopWithBitfieldOnLoopVarOnIntAndUpperBound() {354  struct StructWithBitField {355      int var : 5;356      unsigned limit : 5;357  } value = {};358 359  for(value.var = 0U; value.var < value.limit; ++value.var) {360  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: loop variable has narrower type 'int:5' than iteration's upper bound 'unsigned int:5' [bugprone-too-small-loop-variable]361  }362}363 364void badForLoopWithBitfieldOnLoopVarAndUpperBoundOnInt() {365  struct StructWithBitField {366      unsigned var : 5;367      int limit : 7;368  } value = {};369 370  for(value.var = 0U; value.var < value.limit; ++value.var) {371  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: loop variable has narrower type 'unsigned int:5' than iteration's upper bound 'int:7' [bugprone-too-small-loop-variable]372  }373}374 375void badForLoopWithBitfieldOnLoopVarAndUpperBoundOnPtr() {376  struct StructWithBitField {377      unsigned var : 5, limit : 6;378  } value = {};379 380  StructWithBitField* ptr = &value;381 382  for(ptr->var = 0U; ptr->var < ptr->limit; ++ptr->var) {383  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: loop variable has narrower type 'unsigned int:5' than iteration's upper bound 'unsigned int:6' [bugprone-too-small-loop-variable]384  }385}386 387void goodForLoopWithBitfieldOnUpperBoundOnly() {388  struct S {389    int x : 4;390  } s;391 392  for (int i = 10; i > s.x; --i) {393  }394}395 396void goodForLoopWithIntegersOnUpperBoundOnly() {397  struct S {398    short x;399  } s;400 401  for (int i = 10; i > s.x; --i) {402  }403}404