Align stack when returning structs.
The stack was not aligned when a returned structure was stored on stack. This resulted in destoying of previous values stored on stack. See testcase 119 (tst_struct_return_align) where value d is overwritten.
This commit is contained in:
parent
5b28165fbf
commit
fd6d2180c5
3 changed files with 24 additions and 1 deletions
3
tccgen.c
3
tccgen.c
|
@ -6142,6 +6142,7 @@ special_math_val:
|
||||||
space. Assume register size is power of 2. */
|
space. Assume register size is power of 2. */
|
||||||
if (regsize > align)
|
if (regsize > align)
|
||||||
align = regsize;
|
align = regsize;
|
||||||
|
loc &= -align;
|
||||||
loc = (loc - size) & -align;
|
loc = (loc - size) & -align;
|
||||||
addr = loc;
|
addr = loc;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
@ -6622,7 +6623,7 @@ static void gfunc_return(CType *func_type)
|
||||||
size = type_size(func_type,&align);
|
size = type_size(func_type,&align);
|
||||||
if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
|
if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
|
||||||
(vtop->c.i & (ret_align-1)))
|
(vtop->c.i & (ret_align-1)))
|
||||||
|| (align & (ret_align-1))) {
|
&& (align & (ret_align-1))) {
|
||||||
loc = (loc - size) & -ret_align;
|
loc = (loc - size) & -ret_align;
|
||||||
addr = loc;
|
addr = loc;
|
||||||
type = *func_type;
|
type = *func_type;
|
||||||
|
|
|
@ -99,6 +99,26 @@ void tst_indir_func(void)
|
||||||
tst_indir.print("tst_indir_func %d\n", 10);
|
tst_indir.print("tst_indir_func %d\n", 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct V {
|
||||||
|
int x, y, z;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct V vec(void)
|
||||||
|
{
|
||||||
|
return (struct V) { 1, 2, 3 };
|
||||||
|
}
|
||||||
|
|
||||||
|
void func(float f, struct V v)
|
||||||
|
{
|
||||||
|
printf("%g\n", f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_struct_return_align(void)
|
||||||
|
{
|
||||||
|
float d = 5.0f;
|
||||||
|
func(d, vec());
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (void)
|
main (void)
|
||||||
{
|
{
|
||||||
|
@ -117,4 +137,5 @@ main (void)
|
||||||
tst_pack();
|
tst_pack();
|
||||||
tst_cast();
|
tst_cast();
|
||||||
tst_indir_func();
|
tst_indir_func();
|
||||||
|
tst_struct_return_align();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,3 +4,4 @@ tst_compare: ok
|
||||||
tst_pack: j.f = 5, i.f = 5
|
tst_pack: j.f = 5, i.f = 5
|
||||||
schar to ushort cast: ffff0033
|
schar to ushort cast: ffff0033
|
||||||
tst_indir_func 10
|
tst_indir_func 10
|
||||||
|
5
|
||||||
|
|
Loading…
Reference in a new issue