Allow _Static_assert declarations in structs
This usage has been part of the C grammar since C11 (http://port70.net/~nsz/c/c11/n1570.html#6.7.2.1) and is also supported by gcc and clang.
This commit is contained in:
parent
ac9eeea1d5
commit
ea0c57e90a
2 changed files with 38 additions and 28 deletions
34
tccgen.c
34
tccgen.c
|
@ -4202,6 +4202,8 @@ static void struct_layout(CType *type, AttributeDef *ad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void do_Static_assert(void);
|
||||||
|
|
||||||
/* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
|
/* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
|
||||||
static void struct_decl(CType *type, int u)
|
static void struct_decl(CType *type, int u)
|
||||||
{
|
{
|
||||||
|
@ -4311,6 +4313,10 @@ do_decl:
|
||||||
c = 0;
|
c = 0;
|
||||||
flexible = 0;
|
flexible = 0;
|
||||||
while (tok != '}') {
|
while (tok != '}') {
|
||||||
|
if (tok == TOK_STATIC_ASSERT) {
|
||||||
|
do_Static_assert();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!parse_btype(&btype, &ad1, 0)) {
|
if (!parse_btype(&btype, &ad1, 0)) {
|
||||||
skip(';');
|
skip(';');
|
||||||
continue;
|
continue;
|
||||||
|
@ -8243,18 +8249,7 @@ static void free_inline_functions(TCCState *s)
|
||||||
dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
|
dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 'l' is VT_LOCAL or VT_CONST to define default storage type
|
static void do_Static_assert(void){
|
||||||
or VT_CMP if parsing old style parameter list
|
|
||||||
or VT_JMP if parsing c99 for decl: for (int i = 0, ...) */
|
|
||||||
static int decl(int l)
|
|
||||||
{
|
|
||||||
int v, has_init, r, oldint;
|
|
||||||
CType type, btype;
|
|
||||||
Sym *sym;
|
|
||||||
AttributeDef ad, adbase;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if (tok == TOK_STATIC_ASSERT) {
|
|
||||||
CString error_str;
|
CString error_str;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
@ -8277,6 +8272,21 @@ static int decl(int l)
|
||||||
skip(')');
|
skip(')');
|
||||||
static_assert_out:
|
static_assert_out:
|
||||||
skip(';');
|
skip(';');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 'l' is VT_LOCAL or VT_CONST to define default storage type
|
||||||
|
or VT_CMP if parsing old style parameter list
|
||||||
|
or VT_JMP if parsing c99 for decl: for (int i = 0, ...) */
|
||||||
|
static int decl(int l)
|
||||||
|
{
|
||||||
|
int v, has_init, r, oldint;
|
||||||
|
CType type, btype;
|
||||||
|
Sym *sym;
|
||||||
|
AttributeDef ad, adbase;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (tok == TOK_STATIC_ASSERT) {
|
||||||
|
do_Static_assert();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,15 +191,15 @@ void * _Alignas(16) p1;
|
||||||
|
|
||||||
#define ONE 0
|
#define ONE 0
|
||||||
_Static_assert(ONE == 0, "don't show me this");
|
_Static_assert(ONE == 0, "don't show me this");
|
||||||
_Static_assert(ONE == 1, "ONE is not 1");
|
struct x{ _Static_assert(ONE == 1, "ONE is not 1"); };
|
||||||
|
|
||||||
#elif defined test_static_assert_2
|
#elif defined test_static_assert_2
|
||||||
_Static_assert(1, "1"" is 1");
|
_Static_assert(1, "1"" is 1");
|
||||||
_Static_assert(0, "0"" is 0");
|
struct y { _Static_assert(0, "0"" is 0"); };
|
||||||
|
|
||||||
#elif defined test_static_assert_c2x
|
#elif defined test_static_assert_c2x
|
||||||
_Static_assert(1);
|
_Static_assert(1);
|
||||||
_Static_assert(0);
|
struct z { _Static_assert(0); }
|
||||||
|
|
||||||
#elif defined test_static_assert_empty_string
|
#elif defined test_static_assert_empty_string
|
||||||
_Static_assert(0,"");
|
_Static_assert(0,"");
|
||||||
|
|
Loading…
Reference in a new issue