xref: /llvm-project/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-local-var-array.cpp (revision 644ac2a018c9bf83c9ba256074e552ad7f1fe941)
1*644ac2a0Sjkorous-apple // RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage \
2*644ac2a0Sjkorous-apple // RUN:            -fsafe-buffer-usage-suggestions \
3*644ac2a0Sjkorous-apple // RUN:            -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
4*644ac2a0Sjkorous-apple typedef int * Int_ptr_t;
5*644ac2a0Sjkorous-apple typedef int Int_t;
6*644ac2a0Sjkorous-apple 
simple(unsigned idx)7*644ac2a0Sjkorous-apple void simple(unsigned idx) {
8*644ac2a0Sjkorous-apple   int buffer[10];
9*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:17}:"std::array<int, 10> buffer"
10*644ac2a0Sjkorous-apple   buffer[idx] = 0;
11*644ac2a0Sjkorous-apple }
12*644ac2a0Sjkorous-apple 
array2d(unsigned idx)13*644ac2a0Sjkorous-apple void array2d(unsigned idx) {
14*644ac2a0Sjkorous-apple   int buffer[10][10];
15*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
16*644ac2a0Sjkorous-apple   buffer[idx][idx] = 0;
17*644ac2a0Sjkorous-apple }
18*644ac2a0Sjkorous-apple 
array2d_vla(unsigned sz,unsigned idx)19*644ac2a0Sjkorous-apple void array2d_vla(unsigned sz, unsigned idx) {
20*644ac2a0Sjkorous-apple   int buffer1[10][sz];
21*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
22*644ac2a0Sjkorous-apple   int buffer2[sz][10];
23*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
24*644ac2a0Sjkorous-apple   buffer1[idx][idx] = 0;
25*644ac2a0Sjkorous-apple   buffer2[idx][idx] = 0;
26*644ac2a0Sjkorous-apple }
27*644ac2a0Sjkorous-apple 
array2d_assign_from_elem(unsigned idx)28*644ac2a0Sjkorous-apple void array2d_assign_from_elem(unsigned idx) {
29*644ac2a0Sjkorous-apple   int buffer[10][10];
30*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
31*644ac2a0Sjkorous-apple   int a = buffer[idx][idx];
32*644ac2a0Sjkorous-apple }
33*644ac2a0Sjkorous-apple 
34*644ac2a0Sjkorous-apple void array2d_use(int *);
array2d_call(unsigned idx)35*644ac2a0Sjkorous-apple void array2d_call(unsigned idx) {
36*644ac2a0Sjkorous-apple   int buffer[10][10];
37*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
38*644ac2a0Sjkorous-apple   array2d_use(buffer[idx]);
39*644ac2a0Sjkorous-apple }
array2d_call_vla(unsigned sz,unsigned idx)40*644ac2a0Sjkorous-apple void array2d_call_vla(unsigned sz, unsigned idx) {
41*644ac2a0Sjkorous-apple   int buffer[10][sz];
42*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
43*644ac2a0Sjkorous-apple   array2d_use(buffer[idx]);
44*644ac2a0Sjkorous-apple }
45*644ac2a0Sjkorous-apple 
array2d_typedef(unsigned idx)46*644ac2a0Sjkorous-apple void array2d_typedef(unsigned idx) {
47*644ac2a0Sjkorous-apple   typedef int ten_ints_t[10];
48*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
49*644ac2a0Sjkorous-apple   ten_ints_t buffer[10];
50*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
51*644ac2a0Sjkorous-apple   buffer[idx][idx] = 0;
52*644ac2a0Sjkorous-apple }
53*644ac2a0Sjkorous-apple 
whitespace_in_declaration(unsigned idx)54*644ac2a0Sjkorous-apple void whitespace_in_declaration(unsigned idx) {
55*644ac2a0Sjkorous-apple   int      buffer_w   [       10 ];
56*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:35}:"std::array<int, 10> buffer_w"
57*644ac2a0Sjkorous-apple   buffer_w[idx] = 0;
58*644ac2a0Sjkorous-apple }
59*644ac2a0Sjkorous-apple 
comments_in_declaration(unsigned idx)60*644ac2a0Sjkorous-apple void comments_in_declaration(unsigned idx) {
61*644ac2a0Sjkorous-apple   int   /* [A] */   buffer_w  /* [B] */ [  /* [C] */ 10 /* [D] */  ] ;
62*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:69}:"std::array<int   /* [A] */, /* [C] */ 10 /* [D] */> buffer_w"
63*644ac2a0Sjkorous-apple   buffer_w[idx] = 0;
64*644ac2a0Sjkorous-apple }
65*644ac2a0Sjkorous-apple 
initializer(unsigned idx)66*644ac2a0Sjkorous-apple void initializer(unsigned idx) {
67*644ac2a0Sjkorous-apple   int buffer[3] = {0};
68*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:16}:"std::array<int, 3> buffer"
69*644ac2a0Sjkorous-apple 
70*644ac2a0Sjkorous-apple   int buffer2[3] = {0, 1, 2};
71*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:17}:"std::array<int, 3> buffer2"
72*644ac2a0Sjkorous-apple 
73*644ac2a0Sjkorous-apple   buffer[idx] = 0;
74*644ac2a0Sjkorous-apple   buffer2[idx] = 0;
75*644ac2a0Sjkorous-apple }
76*644ac2a0Sjkorous-apple 
auto_size(unsigned idx)77*644ac2a0Sjkorous-apple void auto_size(unsigned idx) {
78*644ac2a0Sjkorous-apple   int buffer[] = {0, 1, 2};
79*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
80*644ac2a0Sjkorous-apple // FIXME: implement support
81*644ac2a0Sjkorous-apple 
82*644ac2a0Sjkorous-apple   buffer[idx] = 0;
83*644ac2a0Sjkorous-apple }
84*644ac2a0Sjkorous-apple 
universal_initialization(unsigned idx)85*644ac2a0Sjkorous-apple void universal_initialization(unsigned idx) {
86*644ac2a0Sjkorous-apple   int buffer[] {0, 1, 2};
87*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
88*644ac2a0Sjkorous-apple // FIXME: implement support
89*644ac2a0Sjkorous-apple 
90*644ac2a0Sjkorous-apple   buffer[idx] = 0;
91*644ac2a0Sjkorous-apple }
92*644ac2a0Sjkorous-apple 
multi_decl1(unsigned idx)93*644ac2a0Sjkorous-apple void multi_decl1(unsigned idx) {
94*644ac2a0Sjkorous-apple   int a, buffer[10];
95*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
96*644ac2a0Sjkorous-apple // FIXME: implement support
97*644ac2a0Sjkorous-apple 
98*644ac2a0Sjkorous-apple   buffer[idx] = 0;
99*644ac2a0Sjkorous-apple }
100*644ac2a0Sjkorous-apple 
multi_decl2(unsigned idx)101*644ac2a0Sjkorous-apple void multi_decl2(unsigned idx) {
102*644ac2a0Sjkorous-apple   int buffer[10], b;
103*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
104*644ac2a0Sjkorous-apple // FIXME: implement support
105*644ac2a0Sjkorous-apple 
106*644ac2a0Sjkorous-apple   buffer[idx] = 0;
107*644ac2a0Sjkorous-apple }
108*644ac2a0Sjkorous-apple 
local_array_ptr_to_const(unsigned idx,const int * & a)109*644ac2a0Sjkorous-apple void local_array_ptr_to_const(unsigned idx, const int*& a) {
110*644ac2a0Sjkorous-apple   const int * buffer[10] = {a};
111*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:25}:"std::array<const int *, 10> buffer"
112*644ac2a0Sjkorous-apple   a = buffer[idx];
113*644ac2a0Sjkorous-apple }
114*644ac2a0Sjkorous-apple 
local_array_const_ptr(unsigned idx,int * & a)115*644ac2a0Sjkorous-apple void local_array_const_ptr(unsigned idx, int*& a) {
116*644ac2a0Sjkorous-apple   int * const buffer[10] = {a};
117*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:25}:"std::array<int * const, 10> buffer"
118*644ac2a0Sjkorous-apple 
119*644ac2a0Sjkorous-apple   a = buffer[idx];
120*644ac2a0Sjkorous-apple }
121*644ac2a0Sjkorous-apple 
local_array_const_ptr_via_typedef(unsigned idx,int * & a)122*644ac2a0Sjkorous-apple void local_array_const_ptr_via_typedef(unsigned idx, int*& a) {
123*644ac2a0Sjkorous-apple   typedef int * const my_const_ptr;
124*644ac2a0Sjkorous-apple   my_const_ptr buffer[10] = {a};
125*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:26}:"std::array<my_const_ptr, 10> buffer"
126*644ac2a0Sjkorous-apple 
127*644ac2a0Sjkorous-apple   a = buffer[idx];
128*644ac2a0Sjkorous-apple }
129*644ac2a0Sjkorous-apple 
local_array_const_ptr_to_const(unsigned idx,const int * & a)130*644ac2a0Sjkorous-apple void local_array_const_ptr_to_const(unsigned idx, const int*& a) {
131*644ac2a0Sjkorous-apple   const int * const buffer[10] = {a};
132*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:31}:"std::array<const int * const, 10> buffer"
133*644ac2a0Sjkorous-apple 
134*644ac2a0Sjkorous-apple   a = buffer[idx];
135*644ac2a0Sjkorous-apple 
136*644ac2a0Sjkorous-apple }
137*644ac2a0Sjkorous-apple 
138*644ac2a0Sjkorous-apple template<typename T>
unsupported_local_array_in_template(unsigned idx)139*644ac2a0Sjkorous-apple void unsupported_local_array_in_template(unsigned idx) {
140*644ac2a0Sjkorous-apple   T buffer[10];
141*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:.*-[[@LINE-1]]:.*}
142*644ac2a0Sjkorous-apple   buffer[idx] = 0;
143*644ac2a0Sjkorous-apple }
144*644ac2a0Sjkorous-apple // Instantiate the template function to force its analysis.
145*644ac2a0Sjkorous-apple template void unsupported_local_array_in_template<int>(unsigned);
146*644ac2a0Sjkorous-apple 
147*644ac2a0Sjkorous-apple typedef unsigned int my_uint;
typedef_as_elem_type(unsigned idx)148*644ac2a0Sjkorous-apple void typedef_as_elem_type(unsigned idx) {
149*644ac2a0Sjkorous-apple   my_uint buffer[10];
150*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:21}:"std::array<my_uint, 10> buffer"
151*644ac2a0Sjkorous-apple   buffer[idx] = 0;
152*644ac2a0Sjkorous-apple }
153*644ac2a0Sjkorous-apple 
decltype_as_elem_type(unsigned idx)154*644ac2a0Sjkorous-apple void decltype_as_elem_type(unsigned idx) {
155*644ac2a0Sjkorous-apple   int a;
156*644ac2a0Sjkorous-apple   decltype(a) buffer[10];
157*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:25}:"std::array<decltype(a), 10> buffer"
158*644ac2a0Sjkorous-apple   buffer[idx] = 0;
159*644ac2a0Sjkorous-apple }
160*644ac2a0Sjkorous-apple 
macro_as_elem_type(unsigned idx)161*644ac2a0Sjkorous-apple void macro_as_elem_type(unsigned idx) {
162*644ac2a0Sjkorous-apple #define MY_INT int
163*644ac2a0Sjkorous-apple   MY_INT buffer[10];
164*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:.*-[[@LINE-1]]:.*}
165*644ac2a0Sjkorous-apple // FIXME: implement support
166*644ac2a0Sjkorous-apple 
167*644ac2a0Sjkorous-apple   buffer[idx] = 0;
168*644ac2a0Sjkorous-apple #undef MY_INT
169*644ac2a0Sjkorous-apple }
170*644ac2a0Sjkorous-apple 
macro_as_identifier(unsigned idx)171*644ac2a0Sjkorous-apple void macro_as_identifier(unsigned idx) {
172*644ac2a0Sjkorous-apple #define MY_BUFFER buffer
173*644ac2a0Sjkorous-apple   int MY_BUFFER[10];
174*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:20}:"std::array<int, 10> MY_BUFFER"
175*644ac2a0Sjkorous-apple   MY_BUFFER[idx] = 0;
176*644ac2a0Sjkorous-apple #undef MY_BUFFER
177*644ac2a0Sjkorous-apple }
178*644ac2a0Sjkorous-apple 
macro_as_size(unsigned idx)179*644ac2a0Sjkorous-apple void macro_as_size(unsigned idx) {
180*644ac2a0Sjkorous-apple #define MY_TEN 10
181*644ac2a0Sjkorous-apple   int buffer[MY_TEN];
182*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:21}:"std::array<int, MY_TEN> buffer"
183*644ac2a0Sjkorous-apple   buffer[idx] = 0;
184*644ac2a0Sjkorous-apple #undef MY_TEN
185*644ac2a0Sjkorous-apple }
186*644ac2a0Sjkorous-apple 
187*644ac2a0Sjkorous-apple typedef unsigned int my_array[42];
188*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:.*-[[@LINE-1]]:.*}
typedef_as_array_type(unsigned idx)189*644ac2a0Sjkorous-apple void typedef_as_array_type(unsigned idx) {
190*644ac2a0Sjkorous-apple   my_array buffer;
191*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:.*-[[@LINE-1]]:.*}
192*644ac2a0Sjkorous-apple   buffer[idx] = 0;
193*644ac2a0Sjkorous-apple }
194*644ac2a0Sjkorous-apple 
decltype_as_array_type(unsigned idx)195*644ac2a0Sjkorous-apple void decltype_as_array_type(unsigned idx) {
196*644ac2a0Sjkorous-apple   int buffer[42];
197*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:.*-[[@LINE-1]]:.*}
198*644ac2a0Sjkorous-apple   decltype(buffer) buffer2;
199*644ac2a0Sjkorous-apple // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:.*-[[@LINE-1]]:.*}
200*644ac2a0Sjkorous-apple   buffer2[idx] = 0;
201*644ac2a0Sjkorous-apple }
202*644ac2a0Sjkorous-apple 
constant_as_size(unsigned idx)203*644ac2a0Sjkorous-apple void constant_as_size(unsigned idx) {
204*644ac2a0Sjkorous-apple   const unsigned my_const = 10;
205*644ac2a0Sjkorous-apple   int buffer[my_const];
206*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:23}:"std::array<int, my_const> buffer"
207*644ac2a0Sjkorous-apple   buffer[idx] = 0;
208*644ac2a0Sjkorous-apple }
209*644ac2a0Sjkorous-apple 
subscript_negative()210*644ac2a0Sjkorous-apple void subscript_negative() {
211*644ac2a0Sjkorous-apple   int buffer[10];
212*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:17}:"std::array<int, 10> buffer"
213*644ac2a0Sjkorous-apple 
214*644ac2a0Sjkorous-apple   // For constant-size arrays any negative index will lead to buffer underflow.
215*644ac2a0Sjkorous-apple   // std::array::operator[] has unsigned parameter so the value will be casted to unsigned.
216*644ac2a0Sjkorous-apple   // This will very likely be buffer overflow but hardened std::array catch these at runtime.
217*644ac2a0Sjkorous-apple   buffer[-5] = 0;
218*644ac2a0Sjkorous-apple }
219*644ac2a0Sjkorous-apple 
subscript_signed(int signed_idx)220*644ac2a0Sjkorous-apple void subscript_signed(int signed_idx) {
221*644ac2a0Sjkorous-apple   int buffer[10];
222*644ac2a0Sjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:17}:"std::array<int, 10> buffer"
223*644ac2a0Sjkorous-apple 
224*644ac2a0Sjkorous-apple   // For constant-size arrays any negative index will lead to buffer underflow.
225*644ac2a0Sjkorous-apple   // std::array::operator[] has unsigned parameter so the value will be casted to unsigned.
226*644ac2a0Sjkorous-apple   // This will very likely be buffer overflow but hardened std::array catches these at runtime.
227*644ac2a0Sjkorous-apple   buffer[signed_idx] = 0;
228*644ac2a0Sjkorous-apple }
229