brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · 5f37d99 Raw
169 lines · c
1// RUN: %clang_analyze_cc1 -analyzer-checker=core.BitwiseShift \2// RUN:    -analyzer-checker=debug.ExprInspection \3// RUN:    -analyzer-output=text -verify \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.BitwiseShift \10// RUN:    -analyzer-checker=debug.ExprInspection \11// RUN:    -analyzer-config core.BitwiseShift:Pedantic=true \12// RUN:    -analyzer-output=text -verify \13// RUN:    -triple x86_64-pc-linux-gnu -x c++ -std=c++20 %s \14// RUN:    -Wno-shift-count-negative -Wno-shift-negative-value \15// RUN:    -Wno-shift-count-overflow -Wno-shift-overflow \16// RUN:    -Wno-shift-sign-overflow17//18// This test file verifies the default behavior of the BitwiseShift checker,19// which reports the serious logical defects, but doesn't warn on code that's20// legal under C++20 (or later) and widely accepted (but theoretically21// undefined) in other compilation modes.22 23// TEST NEGATIVE RIGHT OPERAND24//===----------------------------------------------------------------------===//25 26int negative_right_operand_literal(void) {27  return 2 << -2;28  // expected-warning@-1 {{Right operand is negative in left shift}}29  // expected-note@-2 {{The result of left shift is undefined because the right operand is negative}}30}31 32int negative_right_operand_symbolic(int left, int right) {33  // expected-note@+2 {{Assuming 'right' is < 0}}34  // expected-note@+1 {{Taking false branch}}35  if (right >= 0)36    return 0;37  return left >> right;38  // expected-warning@-1 {{Right operand is negative in right shift}}39  // expected-note@-2 {{The result of right shift is undefined because the right operand is negative}}40}41 42int negative_right_operand_compound(short arg) {43  // expected-note@+2 {{Assuming 'arg' is < 2}}44  // expected-note@+1 {{Taking false branch}}45  if (arg >= 2 )46    return 0;47  return 2 << (arg - 1 - 1 - 1);48  // expected-warning@-1 {{Right operand is negative in left shift}}49  // expected-note@-2 {{The result of left shift is undefined because the right operand is negative}}50}51 52// TEST TOO LARGE RIGHT OPERAND53//===----------------------------------------------------------------------===//54 55int too_large_right_operand_literal(void) {56  return 2 << 32;57  // expected-warning@-1 {{Left shift by '32' overflows the capacity of 'int'}}58  // expected-note@-2 {{The result of left shift is undefined because the right operand '32' is not smaller than 32, the capacity of 'int'}}59}60 61int too_large_right_operand_exact_symbolic(int arg) {62  // expected-note@+4 {{Assuming 'arg' is > 33}}63  // expected-note@+3 {{Left side of '||' is false}}64  // expected-note@+2 {{Assuming 'arg' is < 35}}65  // expected-note@+1 {{Taking false branch}}66  if (arg <= 33 || arg >= 35)67    return 0;68  return 3 << arg;69  // expected-warning@-1 {{Left shift by '34' overflows the capacity of 'int'}}70  // expected-note@-2 {{The result of left shift is undefined because the right operand '34' is not smaller than 32, the capacity of 'int'}}71}72 73int too_large_right_operand_exact_symbolic_2(char arg) {74  // expected-note@+2 {{Assuming the condition is false}}75  // expected-note@+1 {{Taking false branch}}76  if (arg != ' ')77    return 0;78  return 3 << arg;79  // expected-warning@-1 {{Left shift by '32' overflows the capacity of 'int'}}80  // expected-note@-2 {{The result of left shift is undefined because the right operand '32' is not smaller than 32, the capacity of 'int'}}81}82 83int too_large_right_operand_symbolic(int left, int right) {84  // expected-note@+2 {{Assuming 'right' is > 31}}85  // expected-note@+1 {{Taking false branch}}86  if (right <= 31)87    return 0;88  return left >> right;89  // expected-warning@-1 {{Right shift overflows the capacity of 'int'}}90  // expected-note@-2 {{The result of right shift is undefined because the right operand is >= 32, not smaller than 32, the capacity of 'int'}}91}92 93void clang_analyzer_value(int);94int too_large_right_operand_compound(unsigned short arg) {95  // Note: this would be valid code with an 'unsigned int' because96  // unsigned addition is allowed to overflow.97  clang_analyzer_value(32+arg);98  // expected-warning@-1 {{32s:{ [-2147483648, 2147483647] }}99  // expected-note@-2 {{32s:{ [-2147483648, 2147483647] }}100  return 1 << (32 + arg);101  // expected-warning@-1 {{Left shift overflows the capacity of 'int'}}102  // expected-note@-2 {{The result of left shift is undefined because the right operand is not smaller than 32, the capacity of 'int'}}103  // FIXME: this message should be104  //     {{The result of left shift is undefined because the right operand is >= 32, not smaller than 32, the capacity of 'int'}}105  // but for some reason neither the new logic, nor debug.ExprInspection and106  // clang_analyzer_value reports this range information.107}108 109// TEST STATE UPDATES110//===----------------------------------------------------------------------===//111 112void state_update(char a, int *p) {113  // NOTE: with 'int a' this would not produce a bug report because the engine114  // would not rule out an overflow.115  *p += 1 << a;116  // expected-note@-1 {{Assuming right operand of bit shift is non-negative but less than 32}}117  *p += 1 << (a + 32);118  // expected-warning@-1 {{Left shift overflows the capacity of 'int'}}119  // expected-note@-2 {{The result of left shift is undefined because the right operand is not smaller than 32, the capacity of 'int'}}120}121 122void state_update_2(char a, int *p) {123  *p += 1234 >> (a + 32);124  // expected-note@-1 {{Assuming right operand of bit shift is non-negative but less than 32}}125  *p += 1234 >> a;126  // expected-warning@-1 {{Right operand is negative in right shift}}127  // expected-note@-2 {{The result of right shift is undefined because the right operand is negative}}128}129 130// TEST EXPRESSION TRACKING131//===----------------------------------------------------------------------===//132// Expression tracking a "generic" tool that's used by many other checkers,133// so this is just a minimal test to see that it's activated.134 135void setValue(unsigned *p, unsigned newval) {136  *p = newval;137  // expected-note@-1 {{The value 33 is assigned to 'right'}}138}139 140int expression_tracked_back(void) {141  unsigned left = 115; // expected-note {{'left' initialized to 115}}142  unsigned right;143  setValue(&right, 33);144  // expected-note@-1 {{Calling 'setValue'}}145  // expected-note@-2 {{Passing the value 33 via 2nd parameter 'newval'}}146  // expected-note@-3 {{Returning from 'setValue'}}147 148  return left << right;149  // expected-warning@-1 {{Left shift by '33' overflows the capacity of 'unsigned int'}}150  // expected-note@-2 {{The result of left shift is undefined because the right operand '33' is not smaller than 32, the capacity of 'unsigned int'}}151}152 153// TEST PERMISSIVENESS154//===----------------------------------------------------------------------===//155 156int allow_overflows_and_negative_operands(void) {157  // These are all legal under C++20 and many compilers accept them under158  // earlier standards as well.159  int int_min = 1 << 31; // no-warning160  int this_overflows = 1027 << 30; // no-warning161  return (-2 << 5) + (-3 >> 4); // no-warning162}163 164int double_negative(void) {165  return -2 >> -2;166  // expected-warning@-1 {{Right operand is negative in right shift}}167  // expected-note@-2 {{The result of right shift is undefined because the right operand is negative}}168}169