xref: /llvm-project/clang/test/Analysis/bitwise-shift-pedantic.c (revision 25b9696b61e53a958e217bb3d0eab66350dc187f)
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core.BitwiseShift \
2 // RUN:    -analyzer-config core.BitwiseShift:Pedantic=true \
3 // RUN:    -analyzer-output=text -verify=expected,c \
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-overflow
8 //
9 // RUN: %clang_analyze_cc1 -analyzer-checker=core.BitwiseShift \
10 // RUN:    -analyzer-config core.BitwiseShift:Pedantic=true \
11 // RUN:    -analyzer-output=text -verify=expected,cxx \
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-overflow
16 
17 // This test file verifies the pedantic mode of the BitwiseShift checker, which
18 // also reports issues that are undefined behavior (according to the standard,
19 // under C and in C++ before C++20), but would be accepted by many compilers.
20 
21 // TEST NEGATIVE LEFT OPERAND
22 //===----------------------------------------------------------------------===//
23 
negative_left_operand_literal(void)24 int negative_left_operand_literal(void) {
25   return -2 << 2;
26   // expected-warning@-1 {{Left operand is negative in left shift}}
27   // expected-note@-2 {{The result of left shift is undefined because the left operand is negative}}
28 }
29 
negative_left_operand_symbolic(int left,int right)30 int negative_left_operand_symbolic(int left, int right) {
31   // expected-note@+2 {{Assuming 'left' is < 0}}
32   // expected-note@+1 {{Taking false branch}}
33   if (left >= 0)
34     return 0;
35   return left >> right;
36   // expected-warning@-1 {{Left operand is negative in right shift}}
37   // expected-note@-2 {{The result of right shift is undefined because the left operand is negative}}
38 }
39 
negative_left_operand_compound(short arg)40 int negative_left_operand_compound(short arg) {
41   // expected-note@+2 {{Assuming 'arg' is < 0}}
42   // expected-note@+1 {{Taking false branch}}
43   if (arg >= 0)
44     return 0;
45   return (arg - 3) << 2;
46   // expected-warning@-1 {{Left operand is negative in left shift}}
47   // expected-note@-2 {{The result of left shift is undefined because the left operand is negative}}
48 }
49 
double_negative(void)50 int double_negative(void) {
51   // In this case we still report that the right operand is negative, because
52   // that's the more "serious" issue:
53   return -2 >> -2;
54   // expected-warning@-1 {{Right operand is negative in right shift}}
55   // expected-note@-2 {{The result of right shift is undefined because the right operand is negative}}
56 }
57 
single_unknown_negative(int arg)58 int single_unknown_negative(int arg) {
59   // In this case just one of the operands will be negative, so we end up
60   // reporting the left operand after assuming that the right operand is
61   // positive.
62   // expected-note@+2 {{Assuming 'arg' is not equal to 0}}
63   // expected-note@+1 {{Taking false branch}}
64   if (!arg)
65     return 0;
66   // We're first checking the right operand, record that it must be positive,
67   // then report that then the left argument must be negative.
68   return -arg << arg;
69   // expected-warning@-1 {{Left operand is negative in left shift}}
70   // expected-note@-2 {{The result of left shift is undefined because the left operand is negative}}
71 }
72 
shift_negative_by_zero(int c)73 void shift_negative_by_zero(int c) {
74   // This seems to be innocent, but the standard (before C++20) clearly implies
75   // that this is UB, so we should report it in pedantic mode.
76   c = (-1) << 0;
77   // expected-warning@-1 {{Left operand is negative in left shift}}
78   // expected-note@-2 {{The result of left shift is undefined because the left operand is negative}}
79 }
80 
81 // TEST OVERFLOW OF CONCRETE SIGNED LEFT OPERAND
82 //===----------------------------------------------------------------------===//
83 // (the most complex and least important part of the checker)
84 
concrete_overflow_literal(void)85 int concrete_overflow_literal(void) {
86   // 27 in binary is 11011 (5 bits), when shifted by 28 bits it becomes
87   // 1_10110000_00000000_00000000_00000000
88   return 27 << 28;
89   // expected-warning@-1 {{The shift '27 << 28' overflows the capacity of 'int'}}
90   // cxx-note@-2 {{The shift '27 << 28' is undefined because 'int' can hold only 32 bits (including the sign bit), so 1 bit overflows}}
91   // c-note@-3 {{The shift '27 << 28' is undefined because 'int' can hold only 31 bits (excluding the sign bit), so 2 bits overflow}}
92 }
93 
concrete_overflow_symbolic(int arg)94 int concrete_overflow_symbolic(int arg) {
95   // 29 in binary is 11101 (5 bits), when shifted by 29 bits it becomes
96   // 11_10100000_00000000_00000000_00000000
97 
98   // expected-note@+2 {{Assuming 'arg' is equal to 29}}
99   // expected-note@+1 {{Taking false branch}}
100   if (arg != 29)
101     return 0;
102   return arg << arg;
103   // expected-warning@-1 {{The shift '29 << 29' overflows the capacity of 'int'}}
104   // cxx-note@-2 {{The shift '29 << 29' is undefined because 'int' can hold only 32 bits (including the sign bit), so 2 bits overflow}}
105   // c-note@-3 {{The shift '29 << 29' is undefined because 'int' can hold only 31 bits (excluding the sign bit), so 3 bits overflow}}
106 }
107 
concrete_overflow_language_difference(void)108 int concrete_overflow_language_difference(void) {
109   // 21 in binary is 10101 (5 bits), when shifted by 27 bits it becomes
110   // 10101000_00000000_00000000_00000000
111   // This does not overflow the 32-bit capacity of int, but reaches the sign
112   // bit, which is undefined under C (but accepted in C++ even before C++20).
113   return 21 << 27;
114   // c-warning@-1 {{The shift '21 << 27' overflows the capacity of 'int'}}
115   // c-note@-2 {{The shift '21 << 27' is undefined because 'int' can hold only 31 bits (excluding the sign bit), so 1 bit overflows}}
116 }
117 
concrete_overflow_int_min(void)118 int concrete_overflow_int_min(void) {
119   // Another case that's undefined in C but valid in all C++ versions.
120   // Note the "represented by 1 bit" special case
121   return 1 << 31;
122   // c-warning@-1 {{The shift '1 << 31' overflows the capacity of 'int'}}
123   // c-note@-2 {{The shift '1 << 31' is undefined because 'int' can hold only 31 bits (excluding the sign bit), so 1 bit overflows}}
124 }
125 
concrete_overflow_vague(int arg)126 int concrete_overflow_vague(int arg) {
127   // expected-note@+2 {{Assuming 'arg' is > 25}}
128   // expected-note@+1 {{Taking false branch}}
129   if (arg <= 25)
130     return 0;
131   return 1024 << arg;
132     // expected-warning@-1 {{Left shift of '1024' overflows the capacity of 'int'}}
133   // cxx-note@-2 {{Left shift of '1024' is undefined because 'int' can hold only 32 bits (including the sign bit), so some bits overflow}}
134   // c-note@-3 {{Left shift of '1024' is undefined because 'int' can hold only 31 bits (excluding the sign bit), so some bits overflow}}
135 }
136 
concrete_overflow_vague_only_c(int arg)137 int concrete_overflow_vague_only_c(int arg) {
138   // A third case that's undefined in C but valid in all C++ versions.
139 
140   // c-note@+2 {{Assuming 'arg' is > 20}}
141   // c-note@+1 {{Taking false branch}}
142   if (arg <= 20)
143     return 0;
144   return 1024 << arg;
145   // c-warning@-1 {{Left shift of '1024' overflows the capacity of 'int'}}
146   // c-note@-2 {{Left shift of '1024' is undefined because 'int' can hold only 31 bits (excluding the sign bit), so some bits overflow}}
147 }
148 
concrete_overflow_vague_left(int arg)149 int concrete_overflow_vague_left(int arg) {
150   // This kind of overflow check only handles concrete values on the LHS. With
151   // some effort it would be possible to report errors in cases like this; but
152   // it's probably a waste of time especially considering that overflows of
153   // left shifts became well-defined in C++20.
154 
155   if (arg <= 1024)
156     return 0;
157   return arg << 25; // no-warning
158 }
159 
concrete_overflow_shift_zero(void)160 int concrete_overflow_shift_zero(void) {
161   // This is legal, even in C.
162   // The relevant rule (as paraphrased on cppreference.com) is:
163   // "For signed LHS with nonnegative values, the value of LHS << RHS is
164   // LHS * 2^RHS if it is representable in the promoted type of lhs, otherwise
165   // the behavior is undefined."
166   return 0 << 31; // no-warning
167 }
168