diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-02 19:36:50 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-02 19:37:27 +0900 |
| commit | ee7da1ce9c1efd76bf02e7a5d2591bf8099ef0ca (patch) | |
| tree | 12c5bfb3999a738bd4286334f0bb623bac0f81c9 /src | |
| parent | 76654319325efadf9ef19f4ce181397ad53f6914 (diff) | |
| download | ducc-ee7da1ce9c1efd76bf02e7a5d2591bf8099ef0ca.tar.gz ducc-ee7da1ce9c1efd76bf02e7a5d2591bf8099ef0ca.tar.zst ducc-ee7da1ce9c1efd76bf02e7a5d2591bf8099ef0ca.zip | |
fix: stack offset calculation of local variables of functions having many parameters
`calc_lvar_stack_offset()` previously only checked the offset of the last local variables, but it might be a
passed-by-stack parameter, which had a negative stack offset.
With this change, `calc_lvar_stack_offset()` finds the maximum *positive* offset from local variables.
Diffstat (limited to 'src')
| -rw-r--r-- | src/parse.c | 17 |
1 files changed, 9 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) { |
