1 // RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage \
2 // RUN: -fsafe-buffer-usage-suggestions \
3 // RUN: -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
4 typedef int * Int_ptr_t
;
7 void simple(unsigned idx
) {
9 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:17}:"std::array<int, 10> buffer"
13 void array2d(unsigned idx
) {
15 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
19 void array2d_vla(unsigned sz
, unsigned idx
) {
21 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
23 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
24 buffer1
[idx
][idx
] = 0;
25 buffer2
[idx
][idx
] = 0;
28 void array2d_assign_from_elem(unsigned idx
) {
30 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
31 int a
= buffer
[idx
][idx
];
34 void array2d_use(int *);
35 void array2d_call(unsigned idx
) {
37 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
38 array2d_use(buffer
[idx
]);
40 void array2d_call_vla(unsigned sz
, unsigned idx
) {
42 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
43 array2d_use(buffer
[idx
]);
46 void array2d_typedef(unsigned idx
) {
47 typedef int ten_ints_t
[10];
48 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
49 ten_ints_t buffer
[10];
50 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
54 void whitespace_in_declaration(unsigned idx
) {
56 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:35}:"std::array<int, 10> buffer_w"
60 void comments_in_declaration(unsigned idx
) {
61 int /* [A] */ buffer_w
/* [B] */ [ /* [C] */ 10 /* [D] */ ] ;
62 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:69}:"std::array<int /* [A] */, /* [C] */ 10 /* [D] */> buffer_w"
66 void initializer(unsigned idx
) {
68 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:16}:"std::array<int, 3> buffer"
70 int buffer2
[3] = {0, 1, 2};
71 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:17}:"std::array<int, 3> buffer2"
77 void auto_size(unsigned idx
) {
78 int buffer
[] = {0, 1, 2};
79 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
80 // FIXME: implement support
85 void universal_initialization(unsigned idx
) {
86 int buffer
[] {0, 1, 2};
87 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
88 // FIXME: implement support
93 void multi_decl1(unsigned idx
) {
95 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
96 // FIXME: implement support
101 void multi_decl2(unsigned idx
) {
103 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
104 // FIXME: implement support
109 void local_array_ptr_to_const(unsigned idx
, const int*& a
) {
110 const int * buffer
[10] = {a
};
111 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:25}:"std::array<const int *, 10> buffer"
115 void local_array_const_ptr(unsigned idx
, int*& a
) {
116 int * const buffer
[10] = {a
};
117 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:25}:"std::array<int * const, 10> buffer"
122 void local_array_const_ptr_via_typedef(unsigned idx
, int*& a
) {
123 typedef int * const my_const_ptr
;
124 my_const_ptr buffer
[10] = {a
};
125 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:26}:"std::array<my_const_ptr, 10> buffer"
130 void local_array_const_ptr_to_const(unsigned idx
, const int*& a
) {
131 const int * const buffer
[10] = {a
};
132 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:31}:"std::array<const int * const, 10> buffer"
139 void unsupported_local_array_in_template(unsigned idx
) {
141 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:.*-[[@LINE-1]]:.*}
144 // Instantiate the template function to force its analysis.
145 template void unsupported_local_array_in_template
<int>(unsigned);
147 typedef unsigned int my_uint
;
148 void typedef_as_elem_type(unsigned idx
) {
150 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:21}:"std::array<my_uint, 10> buffer"
154 void decltype_as_elem_type(unsigned idx
) {
156 decltype(a
) buffer
[10];
157 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:25}:"std::array<decltype(a), 10> buffer"
161 void macro_as_elem_type(unsigned idx
) {
164 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:.*-[[@LINE-1]]:.*}
165 // FIXME: implement support
171 void macro_as_identifier(unsigned idx
) {
172 #define MY_BUFFER buffer
174 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:20}:"std::array<int, 10> MY_BUFFER"
179 void macro_as_size(unsigned idx
) {
182 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:21}:"std::array<int, MY_TEN> buffer"
187 typedef unsigned int my_array
[42];
188 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:.*-[[@LINE-1]]:.*}
189 void typedef_as_array_type(unsigned idx
) {
191 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:.*-[[@LINE-1]]:.*}
195 void decltype_as_array_type(unsigned idx
) {
197 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:.*-[[@LINE-1]]:.*}
198 decltype(buffer
) buffer2
;
199 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:.*-[[@LINE-1]]:.*}
203 void constant_as_size(unsigned idx
) {
204 const unsigned my_const
= 10;
205 int buffer
[my_const
];
206 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:23}:"std::array<int, my_const> buffer"
210 void subscript_negative() {
212 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:17}:"std::array<int, 10> buffer"
214 // For constant-size arrays any negative index will lead to buffer underflow.
215 // std::array::operator[] has unsigned parameter so the value will be casted to unsigned.
216 // This will very likely be buffer overflow but hardened std::array catch these at runtime.
220 void subscript_signed(int signed_idx
) {
222 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:17}:"std::array<int, 10> buffer"
224 // For constant-size arrays any negative index will lead to buffer underflow.
225 // std::array::operator[] has unsigned parameter so the value will be casted to unsigned.
226 // This will very likely be buffer overflow but hardened std::array catches these at runtime.
227 buffer
[signed_idx
] = 0;