mirror of
https://github.com/TinyCC/tinycc.git
synced 2025-11-16 04:24:45 +00:00
Do not read past array end in struct return
This commit is contained in:
15
tccgen.c
15
tccgen.c
@@ -6706,11 +6706,16 @@ static void gfunc_return(CType *func_type)
|
||||
/* returning structure packed into registers */
|
||||
int size, addr, align, rc, n;
|
||||
size = type_size(func_type,&align);
|
||||
if ((align & (ret_align - 1))
|
||||
&& ((vtop->r & VT_VALMASK) < VT_CONST /* pointer to struct */
|
||||
|| (vtop->c.i & (ret_align - 1))
|
||||
)) {
|
||||
loc = (loc - size) & -ret_align;
|
||||
if (ret_nregs * regsize > size ||
|
||||
((align & (ret_align - 1))
|
||||
&& ((vtop->r & VT_VALMASK) < VT_CONST /* pointer to struct */
|
||||
|| (vtop->c.i & (ret_align - 1))
|
||||
))) {
|
||||
if (ret_nregs * regsize > size)
|
||||
size = ret_nregs * regsize;
|
||||
if (ret_align > align)
|
||||
align = ret_align;
|
||||
loc = (loc - size) & -align;
|
||||
addr = loc;
|
||||
type = *func_type;
|
||||
vset(&type, VT_LOCAL | VT_LVAL, addr);
|
||||
|
||||
@@ -6,6 +6,10 @@ typedef struct {
|
||||
double d2;
|
||||
} Node;
|
||||
|
||||
typedef struct {
|
||||
int a, b, c;
|
||||
} A;
|
||||
|
||||
Node init(Node self) {
|
||||
self.data[0] = 0;
|
||||
self.data[1] = 1;
|
||||
@@ -25,11 +29,25 @@ void print_data(Node data) {
|
||||
data.d1, data.d2);
|
||||
}
|
||||
|
||||
A test(void)
|
||||
{
|
||||
int i;
|
||||
A arr[30];
|
||||
|
||||
for (i = 0; i < 30; i++)
|
||||
arr[i].b = i;
|
||||
return arr[29];
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
/* This code resulted in a bounds checking error */
|
||||
Node data;
|
||||
A a;
|
||||
dummy (data);
|
||||
char val;
|
||||
data = init (data);
|
||||
print_data(data);
|
||||
a = test();
|
||||
printf("%d\n", a.b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
0 1 2 3 1234 2345
|
||||
29
|
||||
|
||||
Reference in New Issue
Block a user