blob: c6c93a27e4b969277350c38c2d5a3c713e545af3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
// RUN: %clang_cc1 -std=c++20 -Wno-everything -Wunsafe-buffer-usage \
// RUN: -fsafe-buffer-usage-suggestions \
// RUN: -verify %s
// CHECK-NOT: [-Wunsafe-buffer-usage]
void foo(unsigned idx) {
int buffer[10]; // expected-warning{{'buffer' is an unsafe buffer that does not perform bounds checks}}
// expected-note@-1{{change type of 'buffer' to 'std::array' to label it for hardening}}
buffer[idx] = 0; // expected-note{{used in buffer access here}}
}
int global_buffer[10]; // expected-warning{{'global_buffer' is an unsafe buffer that does not perform bounds checks}}
void foo2(unsigned idx) {
global_buffer[idx] = 0; // expected-note{{used in buffer access here}}
}
struct Foo {
int member_buffer[10];
};
void foo2(Foo& f, unsigned idx) {
f.member_buffer[idx] = 0; // expected-warning{{unsafe buffer access}}
}
void constant_idx_safe(unsigned idx) {
int buffer[10];
buffer[9] = 0;
}
void constant_idx_safe0(unsigned idx) {
int buffer[10];
buffer[0] = 0;
}
void constant_idx_unsafe(unsigned idx) {
int buffer[10]; // expected-warning{{'buffer' is an unsafe buffer that does not perform bounds checks}}
// expected-note@-1{{change type of 'buffer' to 'std::array' to label it for hardening}}
buffer[10] = 0; // expected-note{{used in buffer access here}}
}
void constant_id_string(unsigned idx) {
char safe_char = "abc"[1]; // no-warning
safe_char = ""[0];
safe_char = "\0"[0];
char abcd[5] = "abc";
abcd[2]; // no-warning
char unsafe_char = "abc"[3];
unsafe_char = "abc"[-1]; //expected-warning{{unsafe buffer access}}
unsafe_char = ""[1]; //expected-warning{{unsafe buffer access}}
unsafe_char = ""[idx]; //expected-warning{{unsafe buffer access}}
}
|