From a82aff333774f3bd38841d3c167f1add8c473c1c Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Sun, 2 Jul 2023 03:58:02 +0800 Subject: [PATCH] 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) --- tccgen.c | 2 +- tests/tests2/131_return_struct_in_reg.c | 49 ++++++++++++++++++++ tests/tests2/131_return_struct_in_reg.expect | 3 ++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/tests2/131_return_struct_in_reg.c create mode 100644 tests/tests2/131_return_struct_in_reg.expect diff --git a/tccgen.c b/tccgen.c index c582c4ad..f91a43dd 100644 --- a/tccgen.c +++ b/tccgen.c @@ -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; diff --git a/tests/tests2/131_return_struct_in_reg.c b/tests/tests2/131_return_struct_in_reg.c new file mode 100644 index 00000000..911b660a --- /dev/null +++ b/tests/tests2/131_return_struct_in_reg.c @@ -0,0 +1,49 @@ +#include + +#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; +} diff --git a/tests/tests2/131_return_struct_in_reg.expect b/tests/tests2/131_return_struct_in_reg.expect new file mode 100644 index 00000000..301e3b0f --- /dev/null +++ b/tests/tests2/131_return_struct_in_reg.expect @@ -0,0 +1,3 @@ +1234567890abcd 5a5aa5a5f0f00f0f +1234567890abcd 5a5aa5a5f0f00f0f +1234567890abcd 5a5aa5a5f0f00f0f