diff options
author | Michael Forney <mforney@mforney.org> | 2021-10-25 15:00:48 -0700 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2021-10-25 17:01:50 -0700 |
commit | 7ffff16e6745c267b77d23a047f6ca5f20ca71e7 (patch) | |
tree | 7a7ccd3c8b2a8c2dc72cdf343e50ce7bba245cb7 | |
parent | 42fc7b33d3987fc394e5c0d5ce7cb606b110296d (diff) |
decl: Allow alignment > 16 of globals and struct members
-rw-r--r-- | decl.c | 6 | ||||
-rw-r--r-- | test/alignas-local.c | 4 | ||||
-rw-r--r-- | test/alignas-local.qbe | 9 | ||||
-rw-r--r-- | test/alignas-member.c | 4 | ||||
-rw-r--r-- | test/alignas-member.qbe | 1 | ||||
-rw-r--r-- | test/alignas.c | 2 | ||||
-rw-r--r-- | test/alignas.qbe | 2 |
7 files changed, 24 insertions, 4 deletions
@@ -379,7 +379,7 @@ declspecs(struct scope *s, enum storageclass *sc, enum funcspec *fs, int *align) *align = other->align; } else { i = intconstexpr(s, false); - if (i & (i - 1) || i > 16) + if (i & (i - 1)) error(&tok.loc, "invalid alignment: %d", i); if (i) *align = (int)i; @@ -960,8 +960,10 @@ decl(struct scope *s, struct func *f) if (init || d->linkage == LINKNONE) { if (d->linkage != LINKNONE || sc & SCSTATIC) emitdata(d, init); - else + else if (d->align <= 16) funcinit(f, d, init); + else + error(&tok.loc, "unsupported alignment %d for object with automatic storage duration", d->align); d->defined = true; if (d->tentative.next) listremove(&d->tentative); diff --git a/test/alignas-local.c b/test/alignas-local.c new file mode 100644 index 0000000..e1a8667 --- /dev/null +++ b/test/alignas-local.c @@ -0,0 +1,4 @@ +int main(void) { + _Alignas(16) char x; + return (unsigned long)&x % 16; +} diff --git a/test/alignas-local.qbe b/test/alignas-local.qbe new file mode 100644 index 0000000..cff9008 --- /dev/null +++ b/test/alignas-local.qbe @@ -0,0 +1,9 @@ +export +function w $main() { +@start.1 + %.1 =l alloc16 1 +@body.2 + %.2 =l extsw 16 + %.3 =l urem %.1, %.2 + ret %.3 +} diff --git a/test/alignas-member.c b/test/alignas-member.c new file mode 100644 index 0000000..965e42a --- /dev/null +++ b/test/alignas-member.c @@ -0,0 +1,4 @@ +struct { + int x; + _Alignas(32) char s[32]; +} s = {123, "abc"}; diff --git a/test/alignas-member.qbe b/test/alignas-member.qbe new file mode 100644 index 0000000..13aa14f --- /dev/null +++ b/test/alignas-member.qbe @@ -0,0 +1 @@ +export data $s = align 32 { w 123, z 28, b "abc\000", z 28, } diff --git a/test/alignas.c b/test/alignas.c index b714d37..a0a7669 100644 --- a/test/alignas.c +++ b/test/alignas.c @@ -1 +1 @@ -_Alignas(8) int x; +_Alignas(32) long x[4] = {1, 2, 3, 4}; diff --git a/test/alignas.qbe b/test/alignas.qbe index 6dd5505..8758fb2 100644 --- a/test/alignas.qbe +++ b/test/alignas.qbe @@ -1 +1 @@ -export data $x = align 8 { z 4 } +export data $x = align 32 { l 1, l 2, l 3, l 4, } |