@@ -18,7 +18,9 @@ void foo2(unsigned idx) {
18
18
19
19
struct Foo {
20
20
int member_buffer[10 ];
21
+ int x;
21
22
};
23
+
22
24
void foo2 (Foo& f, unsigned idx) {
23
25
f.member_buffer [idx] = 0 ; // expected-warning{{unsafe buffer access}}
24
26
}
@@ -33,6 +35,37 @@ void constant_idx_safe0(unsigned idx) {
33
35
buffer[0 ] = 0 ;
34
36
}
35
37
38
+ int array[10 ]; // expected-warning {{'array' is an unsafe buffer that does not perform bounds checks}}
39
+
40
+ void masked_idx1 (unsigned long long idx, Foo f) {
41
+ // Bitwise and operation
42
+ array[idx & 5 ] = 10 ; // no-warning
43
+ array[5 &idx] = 12 ; // no-warning
44
+ array[idx & 11 & 5 ] = 3 ; // no warning
45
+ array[idx & 11 ] = 20 ; // expected-note{{used in buffer access here}}
46
+ array[idx &=5 ]; // expected-note{{used in buffer access here}}
47
+ array[f.x & 5 ]; // no-warning
48
+ array[5 & f.x ]; // no-warning
49
+ array[f.x & (-5 )]; // expected-note{{used in buffer access here}}
50
+ }
51
+
52
+ typedef unsigned long long uint64_t ;
53
+ typedef unsigned int uint32_t ;
54
+ typedef unsigned char uint8_t ;
55
+
56
+ void type_conversions (uint64_t idx1, uint32_t idx2, uint8_t idx3) {
57
+ array[(uint32_t )idx1 & 3 ];
58
+ array[idx2 & 3 ];
59
+ array[idx3 & 3 ];
60
+ }
61
+
62
+ int array2[5 ]; // expected-warning {{'array2' is an unsafe buffer that does not perform bounds checks}}
63
+
64
+ void masked_idx_safe (unsigned long long idx) {
65
+ array2[6 & 5 ]; // no warning
66
+ array2[6 & idx & (idx + 1 ) & 5 ]; // expected-note{{used in buffer access here}}
67
+ }
68
+
36
69
void constant_idx_unsafe (unsigned idx) {
37
70
int buffer[10 ]; // expected-warning{{'buffer' is an unsafe buffer that does not perform bounds checks}}
38
71
// expected-note@-1{{change type of 'buffer' to 'std::array' to label it for hardening}}
0 commit comments