1
0
Fork 0

Fix invalid load generated by gfunc_return()

On backends that rely on gfunc_return() to handle structures
  returned in registers (like RISC-V), gfunc_return() may generate
  invalid loads for structures without VT_LOCAL and VT_LVAL. This
  commit fixes it and adds a regression test
  (131_return_struct_in_reg)
This commit is contained in:
Yao Zi 2023-07-02 03:58:02 +08:00
parent c92f4f52d9
commit a82aff3337
No known key found for this signature in database
GPG Key ID: A32FA9E5C3BB744D
3 changed files with 53 additions and 1 deletions

View File

@ -6622,7 +6622,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;

View File

@ -0,0 +1,49 @@
#include<stdio.h>
#define DATA 0x1234567890abcd, 0x5a5aa5a5f0f00f0f
struct s {
long int a;
long int b;
};
struct {
struct s d;
} g = { { DATA } }, *gp = &g;
struct s
foo1(void)
{
struct s d = { DATA };
struct s *p = &d;
long int x = 0;
return *p;
}
struct s
foo2(void)
{
long int unused = 0;
return gp->d;
}
struct s
foo3(void)
{
struct s d = { DATA };
long int unused = 0;
return d;
}
int
main(void)
{
struct s d;
d = foo1();
printf("%lx %lx\n", d.a, d.b);
d = foo2();
printf("%lx %lx\n", d.a, d.b);
d = foo3();
printf("%lx %lx\n", d.a, d.b);
return 0;
}

View File

@ -0,0 +1,3 @@
1234567890abcd 5a5aa5a5f0f00f0f
1234567890abcd 5a5aa5a5f0f00f0f
1234567890abcd 5a5aa5a5f0f00f0f