brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.2 KiB · a31424f Raw
135 lines · c
1// RUN: %clang_analyze_cc1 -analyzer-checker=core \2// RUN:    -analyzer-config core.BitwiseShift:Pedantic=true \3// RUN:    -verify=expected,pedantic \4// RUN:    -triple x86_64-pc-linux-gnu -x c %s \5// RUN:    -Wno-shift-count-negative -Wno-shift-negative-value \6// RUN:    -Wno-shift-count-overflow -Wno-shift-overflow \7// RUN:    -Wno-shift-sign-overflow8//9// RUN: %clang_analyze_cc1 -analyzer-checker=core \10// RUN:    -analyzer-config core.BitwiseShift:Pedantic=true \11// RUN:    -verify=expected,pedantic \12// RUN:    -triple x86_64-pc-linux-gnu -x c++ -std=c++14 %s \13// RUN:    -Wno-shift-count-negative -Wno-shift-negative-value \14// RUN:    -Wno-shift-count-overflow -Wno-shift-overflow \15// RUN:    -Wno-shift-sign-overflow16//17// RUN: %clang_analyze_cc1 -analyzer-checker=core \18// RUN:    -verify=expected \19// RUN:    -triple x86_64-pc-linux-gnu -x c++ -std=c++20 %s \20// RUN:    -Wno-shift-count-negative -Wno-shift-negative-value \21// RUN:    -Wno-shift-count-overflow -Wno-shift-overflow \22// RUN:    -Wno-shift-sign-overflow23 24// This test file verifies that the BitwiseShift checker does not crash or25// report false positives (at least on the cases that are listed here...)26// Other core checkers are also enabled to see interactions with e.g.27// core.UndefinedBinaryOperatorResult.28// For the sake of brevity, 'note' output is not checked in this file.29 30// TEST OBVIOUSLY CORRECT CODE31//===----------------------------------------------------------------------===//32 33unsigned shift_unsigned(void) {34  // Shifts of unsigned LHS may overflow, even if the RHS is signed.35  // In shifts the type of the right operand does not affect the type of the36  // calculation and the result.37  return 1024u << 25ll; // no-warning38}39 40int shift_zeroes(void) {41  return 0 << 0; // no-warning42}43 44int no_info(int left, int right) {45  return left << right; // no-warning46}47 48int all_okay(int left, int right) {49  if (left < 0 || right < 0)50    return 42;51  return (left << right) + (left >> right); // no-warning52}53 54// DOCUMENT A LIMITATION OF THE ANALYZER ENGINE55//===----------------------------------------------------------------------===//56 57int signed_arithmetic_good(int left, int right) {58  if (right >= 32)59    return 0;60  return left << (right - 32);61  // expected-warning@-1 {{Right operand is negative in left shift}}62}63 64int signed_arithmetic_bad(int left, int right) {65  // FIXME: The analyzer engine handles overflow of signed values as if it was66  // a valid code path, so in this case it will think that that (right + 32) is67  // either at least 32 *or* very negative after an overflow.68  // As checkOvershift() is called before checkOperandNegative(), the checker69  // will first rule out the case when (right + 32) is larger than 32 and then70  // it reports that it's negative. Swapping the order of the two checks would71  // trigger an analogous fault in signed_aritmetic_good().72  if (right < 0)73    return 0;74  return left << (right + 32);75  // expected-warning@-1 {{Right operand is negative in left shift}}76  // FIXME: we should rather have {{Left shift overflows the capacity of 'int'}}77}78 79// TEST THE EXAMPLES FROM THE DOCUMENTATION80//===----------------------------------------------------------------------===//81 82void basic_examples(int a, int b) {83  if (b < 0) {84    b = a << b; // expected-warning {{Right operand is negative in left shift}}85  } else if (b >= 32) {86    b = a >> b; // expected-warning {{Right shift overflows the capacity of 'int'}}87  }88}89 90int pedantic_examples(int a, int b) {91  if (a < 0) {92    return a >> b; // pedantic-warning {{Left operand is negative in right shift}}93  }94  a = 1000u << 31; // OK, overflow of unsigned shift is well-defined, a == 095  if (b > 10) {96    a = b << 31; // this is UB before C++20, but the checker doesn't warn because97                 // it doesn't know the exact value of b98  }99  return 1000 << 31; // pedantic-warning {{The shift '1000 << 31' overflows the capacity of 'int'}}100}101 102// TEST UNUSUAL CODE THAT SHOULD NOT CRASH103//===----------------------------------------------------------------------===//104 105__int128 large_left(void) {106  // Ensure that we do not crash when the left operand doesn't fit in 64 bits.107  return (__int128) 1 << 63 << 10 << 10; // no-crash108}109 110int large_right(void) {111  // Ensure that we do not crash when the right operand doesn't fit in 64 bits.112  return 1 << ((__int128) 1 << 118); // no-crash113  // expected-warning@-1 {{Left shift by '332306998946228968225951765070086144' overflows the capacity of 'int'}}114}115 116void doubles_cast_to_integer(int *c) {117  *c = 1 << (int)1.5;          // no-crash118  *c = ((int)1.5) << 1;        // no-crash119  *c = ((int)1.5) << (int)1.5; // no-crash120}121 122// TEST CODE THAT WAS TRIGGERING BUGS IN EARLIER REVISIONS123//===----------------------------------------------------------------------===//124 125unsigned int strange_cast(unsigned short sh) {126  // This testcase triggers a bug in the constant folding (it "forgets" the127  // cast), which is silenced in SimpleSValBuilder::evalBinOpNN() with an ugly128  // workaround, because otherwise it would lead to a false positive from129  // core.UndefinedBinaryOperatorResult.130  unsigned int i;131  sh++;132  for (i=0; i<sh; i++) {}133  return (unsigned int) ( ((unsigned int) sh) << 16 ); // no-warning134}135