~mcf/cproc

f701c0c645abfd94c3ccedf38cbb0fe9f1414141 — Michael Forney 26 days ago ebdae64
decl: Allow _Static_assert in struct declaration
2 files changed, 30 insertions(+), 24 deletions(-)

M decl.c
A test/static-assert-struct.c
M decl.c => decl.c +26 -24
@@ 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)
{

A test/static-assert-struct.c => test/static-assert-struct.c +4 -0
@@ 0,0 1,4 @@
struct s {
	int x;
	_Static_assert(1, "");
};