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. */
|
||||
if (regsize > align)
|
||||
align = regsize;
|
||||
loc &= -align;
|
||||
loc = (loc - size) & -align;
|
||||
addr = loc;
|
||||
offset = 0;
|
||||
|
@ -6622,7 +6623,7 @@ static void gfunc_return(CType *func_type)
|
|||
size = type_size(func_type,&align);
|
||||
if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
|
||||
(vtop->c.i & (ret_align-1)))
|
||||
|| (align & (ret_align-1))) {
|
||||
&& (align & (ret_align-1))) {
|
||||
loc = (loc - size) & -ret_align;
|
||||
addr = loc;
|
||||
type = *func_type;
|
||||
|
|
|
@ -99,6 +99,26 @@ void tst_indir_func(void)
|
|||
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
|
||||
main (void)
|
||||
{
|
||||
|
@ -117,4 +137,5 @@ main (void)
|
|||
tst_pack();
|
||||
tst_cast();
|
||||
tst_indir_func();
|
||||
tst_struct_return_align();
|
||||
}
|
||||
|
|
|
@ -4,3 +4,4 @@ tst_compare: ok
|
|||
tst_pack: j.f = 5, i.f = 5
|
||||
schar to ushort cast: ffff0033
|
||||
tst_indir_func 10
|
||||
5
|
||||
|
|
Loading…
Reference in a new issue