diff options
| -rw-r--r-- | src/parse.c | 17 | ||||
| -rw-r--r-- | tests/functions.c | 9 |
2 files changed, 18 insertions, 8 deletions
diff --git a/src/parse.c b/src/parse.c index 308277f..f7fec94 100644 --- a/src/parse.c +++ b/src/parse.c @@ -237,15 +237,16 @@ static int find_lvar(Parser* p, const char* name) { } static int calc_lvar_stack_offset(Parser* p, Type* ty) { - int offset; - if (p->lvars.len == 0) { - offset = 0; - } else { - offset = p->lvars.data[p->lvars.len - 1].stack_offset; - if (offset < 0) - offset = 0; + int last_offset = 0; + for (int i = p->lvars.len - 1; i >= 0; i--) { + int offset = p->lvars.data[i].stack_offset; + // Skip a passed-by-stack parameter. + if (offset <= 0) + continue; + last_offset = offset; + break; } - return to_aligned(offset + type_sizeof(ty), type_alignof(ty)); + return to_aligned(last_offset + type_sizeof(ty), type_alignof(ty)); } static int add_lvar(Parser* p, const char* name, Type* ty, int stack_offset) { diff --git a/tests/functions.c b/tests/functions.c index 6e4622c..4911d7c 100644 --- a/tests/functions.c +++ b/tests/functions.c @@ -100,6 +100,12 @@ int f10() { return 12345; } +int f11(int* a, int* b, int* c, int* d, int* e, int* f, int* g) { + int x = 99; + int* local = &x; + return *a + *b + *c + *d + *e + *f + *g + *local; +} + int sum(int n, ...) { va_list args; va_start(args, n); @@ -143,6 +149,9 @@ int main() { S s; s.x = 5; s.y = 6; + int v1 = 1, v2 = 2, v3 = 3, v4 = 4, v5 = 5, v6 = 6, v7 = 7; + ASSERT_EQ(1 + 2 + 3 + 4 + 5 + 6 + 7 + 99, f11(&v1, &v2, &v3, &v4, &v5, &v6, &v7)); + ASSERT_EQ(1, f9(0, 1, 2, 3, 4, s, 7, 8)); ASSERT_EQ(2, f9(1, 1, 2, 3, 4, s, 7, 8)); ASSERT_EQ(3, f9(2, 1, 2, 3, 4, s, 7, 8)); |
