1 // RUN: %clang_cc1 -Wunsafe-buffer-usage -fsafe-buffer-usage-suggestions \
2 // RUN: -std=c++20 -verify=expected %s
3 // RUN: %clang_cc1 -Wunsafe-buffer-usage -fsafe-buffer-usage-suggestions \
4 // RUN: -mllvm -debug-only=SafeBuffers \
5 // RUN: -std=c++20 -verify=expected,debug %s
6
7 // A generic -debug would also enable our notes. This is probably fine.
8 //
9 // RUN: %clang_cc1 -Wunsafe-buffer-usage -fsafe-buffer-usage-suggestions \
10 // RUN: -std=c++20 -mllvm -debug \
11 // RUN: -verify=expected,debug %s
12
13 // This test file checks the behavior under the assumption that no fixits
14 // were emitted for the test cases. If -Wunsafe-buffer-usage is improved
15 // to support these cases (thus failing the test), the test should be changed
16 // to showcase a different unsupported example.
17 //
18 // RUN: %clang_cc1 -Wunsafe-buffer-usage -fsafe-buffer-usage-suggestions \
19 // RUN: -mllvm -debug-only=SafeBuffers \
20 // RUN: -std=c++20 -fdiagnostics-parseable-fixits %s \
21 // RUN: 2>&1 | FileCheck %s
22 // CHECK-NOT: fix-it:
23
24 // This debugging facility is only available in debug builds.
25 //
26 // REQUIRES: asserts
27
foo()28 void foo() {
29 int *x = new int[10]; // expected-warning{{'x' is an unsafe pointer used for buffer access}}
30 x[5] = 10; // expected-note{{used in buffer access here}}
31 int z = x[-1]; // expected-note{{used in buffer access here}} \
32 // debug-note{{safe buffers debug: gadget 'ULCArraySubscript' refused to produce a fix}}
33 }
34
failed_multiple_decl()35 void failed_multiple_decl() {
36 int *a = new int[4], b; // expected-warning{{'a' is an unsafe pointer used for buffer access}} \
37 // debug-note{{safe buffers debug: failed to produce fixit for declaration 'a' : multiple VarDecls}}
38 a[4] = 3; // expected-note{{used in buffer access here}}
39 }
40
failed_param_var_decl(int * a=new int[3])41 void failed_param_var_decl(int *a =new int[3]) { // expected-warning{{'a' is an unsafe pointer used for buffer access}} \
42 // debug-note{{safe buffers debug: failed to produce fixit for declaration 'a' : has default arg}}
43 a[4] = 6; // expected-note{{used in buffer access here}}
44 }
45
unclaimed_use()46 void unclaimed_use() {
47 int *a = new int[3]; // expected-warning{{'a' is an unsafe pointer used for buffer access}}
48 a[2] = 9; // expected-note{{used in buffer access here}}
49 int *b = a++; // expected-note{{used in pointer arithmetic here}} \
50 // debug-note{{safe buffers debug: failed to produce fixit for 'a' : has an unclaimed use}}
51 }
52
implied_unclaimed_var(int * b)53 void implied_unclaimed_var(int *b) { // expected-warning{{'b' is an unsafe pointer used for buffer access}}
54 int *a = new int[3]; // expected-warning{{'a' is an unsafe pointer used for buffer access}}
55 a[4] = 7; // expected-note{{used in buffer access here}}
56 a = b; // debug-note{{safe buffers debug: gadget 'PtrToPtrAssignment' refused to produce a fix}}
57 b++; // expected-note{{used in pointer arithmetic here}} \
58 // debug-note{{safe buffers debug: failed to produce fixit for 'b' : has an unclaimed use}}
59 }
60
61 int *a = new int[3]; // expected-warning{{'a' is an unsafe pointer used for buffer access}} \
62 // debug-note{{safe buffers debug: failed to produce fixit for 'a' : neither local nor a parameter}}
test_globals()63 void test_globals() {
64 a[7] = 4; // expected-note{{used in buffer access here}}
65 }
66
test_decomp_decl()67 void test_decomp_decl() {
68 int a[2] = {1, 2};
69 auto [x, y] = a;
70 x = 9;
71 }
72
test_claim_use_multiple()73 void test_claim_use_multiple() {
74 int *a = new int[8]; // expected-warning{{'a' is an unsafe pointer used for buffer access}}
75 a[6] = 9; // expected-note{{used in buffer access here}}
76 a++; // expected-note{{used in pointer arithmetic here}} \
77 // debug-note{{safe buffers debug: failed to produce fixit for 'a' : has an unclaimed use}}
78 }
79
80 struct S
81 {
82 int *x;
83 };
84
f()85 S f() { return S{new int[4]}; }
86
test_struct_claim_use()87 void test_struct_claim_use() {
88 auto [x] = f();
89 x[6] = 8; // expected-warning{{unsafe buffer access}}
90 x++; // expected-warning{{unsafe pointer arithmetic}}
91 }
92
93 void use(int*);
array2d(int idx)94 void array2d(int idx) {
95 int buffer[10][5]; // expected-warning{{'buffer' is an unsafe buffer that does not perform bounds checks}}
96 use(buffer[idx]); // expected-note{{used in buffer access here}} \
97 // debug-note{{safe buffers debug: failed to produce fixit for 'buffer' : has an unclaimed use}}
98 }
99