diff options
-rw-r--r-- | decl.c | 4 | ||||
-rw-r--r-- | qbe.c | 12 | ||||
-rw-r--r-- | test/alignas-local-32.c | 4 | ||||
-rw-r--r-- | test/alignas-local-32.qbe | 11 |
4 files changed, 26 insertions, 5 deletions
@@ -960,10 +960,8 @@ decl(struct scope *s, struct func *f) if (init || d->linkage == LINKNONE) { if (d->linkage != LINKNONE || sc & SCSTATIC) emitdata(d, init); - else if (d->align <= 16) - funcinit(f, d, init); else - error(&tok.loc, "unsupported alignment %d for object with automatic storage duration", d->align); + funcinit(f, d, init); d->defined = true; if (d->tentative.next) listremove(&d->tentative); @@ -259,6 +259,7 @@ funcalloc(struct func *f, struct decl *d) { enum instkind op; struct inst *inst; + unsigned long long size; assert(!d->type->incomplete); assert(d->type->size > 0); @@ -266,17 +267,24 @@ funcalloc(struct func *f, struct decl *d) d->align = d->type->align; else if (d->align < d->type->align) error(&tok.loc, "object requires alignment %d, which is stricter than %d", d->type->align, d->align); + size = d->type->size; switch (d->align) { case 1: case 2: case 4: op = IALLOC4; break; case 8: op = IALLOC8; break; + default: size += d->align - 16; /* fallthrough */ case 16: op = IALLOC16; break; - default: - fatal("internal error: invalid alignment: %d\n", d->align); } inst = mkinst(f, op, ptrclass, mkintconst(size), NULL); arrayaddptr(&f->start->insts, inst); + if (d->align > 16) { + /* TODO: implement alloc32 in QBE and use that instead */ + inst = mkinst(f, IADD, ptrclass, &inst->res, mkintconst(d->align - 16)); + arrayaddptr(&f->start->insts, inst); + inst = mkinst(f, IAND, ptrclass, &inst->res, mkintconst(-d->align)); + arrayaddptr(&f->start->insts, inst); + } d->value = &inst->res; } diff --git a/test/alignas-local-32.c b/test/alignas-local-32.c new file mode 100644 index 0000000..e69a105 --- /dev/null +++ b/test/alignas-local-32.c @@ -0,0 +1,4 @@ +int main(void) { + _Alignas(32) char x; + return (unsigned long)&x % 32; +} diff --git a/test/alignas-local-32.qbe b/test/alignas-local-32.qbe new file mode 100644 index 0000000..53bfab3 --- /dev/null +++ b/test/alignas-local-32.qbe @@ -0,0 +1,11 @@ +export +function w $main() { +@start.1 + %.1 =l alloc16 17 + %.2 =l add %.1, 16 + %.3 =l and %.2, 18446744073709551584 +@body.2 + %.4 =l extsw 32 + %.5 =l urem %.3, %.4 + ret %.5 +} |