xref: /llvm-project/clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp (revision 6fce42f89a2c3f12b019bd3d7fef3e8db2d4671f)
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