aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-02 19:36:50 +0900
committernsfisis <nsfisis@gmail.com>2026-05-02 19:37:27 +0900
commitee7da1ce9c1efd76bf02e7a5d2591bf8099ef0ca (patch)
tree12c5bfb3999a738bd4286334f0bb623bac0f81c9 /src
parent76654319325efadf9ef19f4ce181397ad53f6914 (diff)
downloadducc-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.c17
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) {