diff options
author | Michael Forney <mforney@mforney.org> | 2021-04-11 17:44:35 -0700 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2021-04-11 17:44:35 -0700 |
commit | f701c0c645abfd94c3ccedf38cbb0fe9f1414141 (patch) | |
tree | 375eb5f227cf521e52287f855259b623a7c1b9e1 | |
parent | ebdae640721cd7be00db01b6e5d0793b46926f3b (diff) |
decl: Allow _Static_assert in struct declaration
-rw-r--r-- | decl.c | 50 | ||||
-rw-r--r-- | test/static-assert-struct.c | 4 |
2 files changed, 30 insertions, 24 deletions
@@ -750,6 +750,30 @@ addmember(struct structbuilder *b, struct qualtype mt, char *name, int align, ui t->align = align; } +static bool +staticassert(struct scope *s) +{ + struct expr *e; + uint64_t c; + + if (!consume(T_STATIC_ASSERT)) + return false; + expect(TLPAREN, "after _Static_assert"); + c = intconstexpr(s, true); + if (consume(TCOMMA)) { + e = assignexpr(s); + if (!e->decayed || e->base->kind != EXPRSTRING) + error(&tok.loc, "expected string literal after static assertion expression"); + if (!c) + error(&tok.loc, "static assertion failed: %.*s", (int)e->base->string.size, e->base->string.data); + } else if (!c) { + error(&tok.loc, "static assertion failed"); + } + expect(TRPAREN, "after static assertion"); + expect(TSEMICOLON, "after static assertion"); + return true; +} + static void structdecl(struct scope *s, struct structbuilder *b) { @@ -758,6 +782,8 @@ structdecl(struct scope *s, struct structbuilder *b) uint64_t width; int align; + if (staticassert(s)) + return; base = declspecs(s, NULL, NULL, &align); if (!base.type) error(&tok.loc, "no type in struct member declaration"); @@ -859,30 +885,6 @@ declcommon(struct scope *s, enum declkind kind, char *name, char *asmname, struc return d; } -static bool -staticassert(struct scope *s) -{ - struct expr *e; - uint64_t c; - - if (!consume(T_STATIC_ASSERT)) - return false; - expect(TLPAREN, "after _Static_assert"); - c = intconstexpr(s, true); - if (consume(TCOMMA)) { - e = assignexpr(s); - if (!e->decayed || e->base->kind != EXPRSTRING) - error(&tok.loc, "expected string literal after static assertion expression"); - if (!c) - error(&tok.loc, "static assertion failed: %.*s", (int)e->base->string.size, e->base->string.data); - } else if (!c) { - error(&tok.loc, "static assertion failed"); - } - expect(TRPAREN, "after static assertion"); - expect(TSEMICOLON, "after static assertion"); - return true; -} - bool decl(struct scope *s, struct func *f) { diff --git a/test/static-assert-struct.c b/test/static-assert-struct.c new file mode 100644 index 0000000..3b9f97d --- /dev/null +++ b/test/static-assert-struct.c @@ -0,0 +1,4 @@ +struct s { + int x; + _Static_assert(1, ""); +}; |