aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2021-10-27 19:31:24 -0700
committerMichael Forney <mforney@mforney.org>2021-12-06 13:51:58 -0800
commit28961f9197c8c5356f29fffac0cc322788441759 (patch)
tree6be913ce424d5de5e117f4791fee22b5d9db2bd9
parent8e39120d8ef8a5b8267771d2bc037dd1a95850f8 (diff)
decl: Use strictest alignment when multiple specifiers are present
This is specified by the last sentence in C11 6.7.5p6.
-rw-r--r--decl.c14
-rw-r--r--test/alignas-multiple.c1
-rw-r--r--test/alignas-multiple.qbe1
3 files changed, 7 insertions, 9 deletions
diff --git a/decl.c b/decl.c
index d31196f..68fc2d0 100644
--- a/decl.c
+++ b/decl.c
@@ -375,15 +375,11 @@ declspecs(struct scope *s, enum storageclass *sc, enum funcspec *fs, int *align)
next();
expect(TLPAREN, "after '_Alignas'");
other = typename(s, NULL);
- if (other) {
- *align = other->align;
- } else {
- i = intconstexpr(s, false);
- if (i & (i - 1))
- error(&tok.loc, "invalid alignment: %d", i);
- if (i)
- *align = (int)i;
- }
+ i = other ? other->align : intconstexpr(s, false);
+ if (i & (i - 1))
+ error(&tok.loc, "invalid alignment: %d", i);
+ if (i > *align)
+ *align = i;
expect(TRPAREN, "to close '_Alignas' specifier");
break;
diff --git a/test/alignas-multiple.c b/test/alignas-multiple.c
new file mode 100644
index 0000000..7fc2199
--- /dev/null
+++ b/test/alignas-multiple.c
@@ -0,0 +1 @@
+_Alignas(8) _Alignas(4) char x;
diff --git a/test/alignas-multiple.qbe b/test/alignas-multiple.qbe
new file mode 100644
index 0000000..fd85074
--- /dev/null
+++ b/test/alignas-multiple.qbe
@@ -0,0 +1 @@
+export data $x = align 8 { z 1 }