History

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.

Petr Skocik committed 3 years ago

Commit ea0c57e1 parent ac9eeea2 files · +38 −28Browse files

Unified · Split

2 files
  1. tccgen.c +35 −25
  2. tests/tests2/60_errors_and_warnings.c +3 −3
tccgen.c+35−25
@@ -4202,6 +4202,8 @@ static void struct_layout(CType *type, AttributeDef *ad) · 4201 unmodified lines
42024202 }
42034203 }
42044204
4205+static void do_Static_assert(void);
4206+
42054207 /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
42064208 static void struct_decl(CType *type, int u)
42074209 {
@@ -4311,6 +4313,10 @@ do_decl: · 103 unmodified lines
43114313 c = 0;
43124314 flexible = 0;
43134315 while (tok != '}') {
4316+ if (tok == TOK_STATIC_ASSERT) {
4317+ do_Static_assert();
4318+ continue;
4319+ }
43144320 if (!parse_btype(&btype, &ad1, 0)) {
43154321 skip(';');
43164322 continue;
@@ -8243,6 +8249,31 @@ static void free_inline_functions(TCCState *s) · 3926 unmodified lines
82438249 dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
82448250 }
82458251
8252+static void do_Static_assert(void){
8253+ CString error_str;
8254+ int c;
8255+
8256+ next();
8257+ skip('(');
8258+ c = expr_const();
8259+
8260+ if (tok == ')') {
8261+ if (!c)
8262+ tcc_error("_Static_assert fail");
8263+ next();
8264+ goto static_assert_out;
8265+ }
8266+
8267+ skip(',');
8268+ parse_mult_str(&error_str, "string constant");
8269+ if (c == 0)
8270+ tcc_error("%s", (char *)error_str.data);
8271+ cstr_free(&error_str);
8272+ skip(')');
8273+ static_assert_out:
8274+ skip(';');
8275+}
8276+
82468277 /* 'l' is VT_LOCAL or VT_CONST to define default storage type
82478278 or VT_CMP if parsing old style parameter list
82488279 or VT_JMP if parsing c99 for decl: for (int i = 0, ...) */
@@ -8254,31 +8285,10 @@ static int decl(int l) · 5 unmodified lines
82548285 AttributeDef ad, adbase;
82558286
82568287 while (1) {
8257− if (tok == TOK_STATIC_ASSERT) {
8258− CString error_str;
8259− int c;
8260−
8261− next();
8262− skip('(');
8263− c = expr_const();
8264−
8265− if (tok == ')') {
8266− if (!c)
8267− tcc_error("_Static_assert fail");
8268− next();
8269− goto static_assert_out;
8270− }
8271−
8272− skip(',');
8273− parse_mult_str(&error_str, "string constant");
8274− if (c == 0)
8275− tcc_error("%s", (char *)error_str.data);
8276− cstr_free(&error_str);
8277− skip(')');
8278− static_assert_out:
8279− skip(';');
8280− continue;
8281− }
8288+ if (tok == TOK_STATIC_ASSERT) {
8289+ do_Static_assert();
8290+ continue;
8291+ }
82828292
82838293 oldint = 0;
82848294 if (!parse_btype(&btype, &adbase, l == VT_LOCAL)) {
tests/tests2/60_errors_and_warnings.c+3−3
@@ -191,15 +191,15 @@ void * _Alignas(16) p1; · 190 unmodified lines
191191
192192 #define ONE 0
193193 _Static_assert(ONE == 0, "don't show me this");
194− _Static_assert(ONE == 1, "ONE is not 1");
194+ struct x{ _Static_assert(ONE == 1, "ONE is not 1"); };
195195
196196 #elif defined test_static_assert_2
197197 _Static_assert(1, "1"" is 1");
198− _Static_assert(0, "0"" is 0");
198+struct y { _Static_assert(0, "0"" is 0"); };
199199
200200 #elif defined test_static_assert_c2x
201201 _Static_assert(1);
202− _Static_assert(0);
202+struct z { _Static_assert(0); }
203203
204204 #elif defined test_static_assert_empty_string
205205 _Static_assert(0,"");

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t