History

tccgen: more of scope hacks

* case 1: local scope of 'ff' int main() { int ff = 123; { int ff(int): ff(456) }} * case 2: linkage of a static extern symbol (older gcc did allow that) static int ff(int); int main() { int ff(int): ff(456) } Also: - cleanup enum, let sym_push() handle redefinition - just mark incomplete array base types, unshare only when needed (in decl_initializer_alloc()) - fix sizeof empty array (= 0) : int ii[] = {}; - rename 'Sym' members used by __attribute__((cleanup(f)))

grischka committed 1 year ago

Commit 38ab5f61 parent ce4de9610 files · +288 −144Browse files

Unified · Split

10 files
  1. tcc.h +14 −6
  2. tccasm.c +1 −1
  3. tccgen.c +145 −110
  4. tests/tests2/129_scopes.c +77 −14
  5. tests/tests2/129_scopes.expect +8 −2
  6. tests/tests2/35_sizeof.c +24 −8
  7. tests/tests2/35_sizeof.expect +7 −2
  8. tests/tests2/39_typedef.c +9 −0
  9. tests/tests2/39_typedef.expect +2 −0
  10. tests/tests2/60_errors_and_warnings.expect +1 −1
tcc.h+14−6
@@ -552,13 +552,17 @@ typedef struct Sym { · 551 unmodified lines
552 CType type; /* associated type */552 CType type; /* associated type */
553 union {553 union {
554 struct Sym *next; /* next related symbol (for fields and anoms) */554 struct Sym *next; /* next related symbol (for fields and anoms) */
555 int *e; /* expanded token stream */555 int *e; /* expanded token stream with preprocessor macros */
556 int asm_label; /* associated asm label */556 int asm_label; /* associated asm label */
557 struct Sym *cleanupstate; /* in defined labels */557 struct Sym *cleanupstate; /* in defined labels */
558 int *vla_array_str; /* vla array code */558 int *vla_array_str; /* vla array code */
559 };559 };
560 struct Sym *prev; /* prev symbol in stack */560 struct Sym *prev; /* prev symbol in stack */
561 struct Sym *prev_tok; /* previous symbol for this token */561 union {
562 struct Sym *prev_tok; /* previous symbol for this token */
563 struct Sym *cleanup_sym; /* symbol from __attribute__((cleanup())) */
564 struct Sym *cleanup_label; /* label in 'pending_gotos' chain */
565 };
562} Sym;566} Sym;
563 567
564/* section definition */568/* section definition */
@@ -1074,7 +1078,7 @@ struct filespec { · 509 unmodified lines
1074 1078
1075#define VT_UNION (1 << VT_STRUCT_SHIFT | VT_STRUCT)1079#define VT_UNION (1 << VT_STRUCT_SHIFT | VT_STRUCT)
1076#define VT_ENUM (2 << VT_STRUCT_SHIFT) /* integral type is an enum really */1080#define VT_ENUM (2 << VT_STRUCT_SHIFT) /* integral type is an enum really */
1077#define VT_ENUM_VAL (4 << VT_STRUCT_SHIFT) /* integral type is an enum constant really */1081#define VT_ENUM_VAL (3 << VT_STRUCT_SHIFT) /* integral type is an enum constant really */
1078 1082
1079#define IS_ENUM(t) ((t & VT_STRUCT_MASK) == VT_ENUM)1083#define IS_ENUM(t) ((t & VT_STRUCT_MASK) == VT_ENUM)
1080#define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL)1084#define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL)
@@ -1087,9 +1091,13 @@ struct filespec { · 6 unmodified lines
1087#define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))1091#define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))
1088 1092
1089/* symbol was created by tccasm.c first */1093/* symbol was created by tccasm.c first */
1090#define VT_ASM (VT_VOID | 1 << VT_STRUCT_SHIFT)1094#define VT_ASM (VT_VOID | 4 << VT_STRUCT_SHIFT)
1091#define VT_ASM_FUNC (VT_ASM | 2 << VT_STRUCT_SHIFT)1095#define VT_ASM_FUNC (VT_VOID | 5 << VT_STRUCT_SHIFT)
1092#define IS_ASM_SYM(sym) (((sym)->type.t & (VT_BTYPE | VT_ASM)) == VT_ASM)1096#define IS_ASM_SYM(sym) (((sym)->type.t & ((VT_BTYPE|VT_STRUCT_MASK) & ~(1<<VT_STRUCT_SHIFT))) == VT_ASM)
1097#define IS_ASM_FUNC(t) ((t & (VT_BTYPE|VT_STRUCT_MASK)) == VT_ASM_FUNC)
1098
1099/* base type is array (from typedef/typeof) */
1100#define VT_BT_ARRAY (6 << VT_STRUCT_SHIFT)
1093 1101
1094/* general: set/get the pseudo-bitfield value for bit-mask M */1102/* general: set/get the pseudo-bitfield value for bit-mask M */
1095#define BFVAL(M,N) ((unsigned)((M) & ~((M) << 1)) * (N))1103#define BFVAL(M,N) ((unsigned)((M) & ~((M) << 1)) * (N))
tccasm.c+1−1
@@ -842,7 +842,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 841 unmodified lines
842 842
843 if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {843 if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
844 if (IS_ASM_SYM(sym))844 if (IS_ASM_SYM(sym))
845 sym->type.t = (sym->type.t & ~VT_ASM) | VT_ASM_FUNC;845 sym->type.t |= VT_ASM_FUNC;
846 st_type = STT_FUNC;846 st_type = STT_FUNC;
847 set_st_type:847 set_st_type:
848 if (sym->c) {848 if (sym->c) {
tccgen.c+145−110
@@ -341,8 +341,8 @@ ST_FUNC void check_vstack(void) · 340 unmodified lines
341 (int)(vtop - vstack + 1));341 (int)(vtop - vstack + 1));
342}342}
343 343
344/* vstack debugging aid */
345#if 0344#if 0
345/* dump 'b' vstack entries starting with 'a' */
346void pv (const char *lbl, int a, int b)346void pv (const char *lbl, int a, int b)
347{347{
348 int i;348 int i;
@@ -352,6 +352,27 @@ void pv (const char *lbl, int a, int b) · 3 unmodified lines
352 lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);352 lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
353 }353 }
354}354}
355
356/* dump symbols on stack from s ... last */
357static inline void psyms(const char *msg, Sym *s, Sym *last)
358{
359 printf("%-8s scope v c r type.t\n", msg);
360 while (s && s != last) {
361 printf(" %8x %08x %08x %08x %08x %s\n",
362 s->sym_scope, s->v, s->c, s->r, s->type.t, get_tok_str(s->v, 0));
363 s = s->prev;
364 }
365}
366
367static void type_to_str(char *buf, int buf_size, CType *type, const char *varstr);
368
369/* print type */
370static void ptype(CType *type, int v)
371{
372 char buf[500];
373 type_to_str(buf, sizeof(buf), type, get_tok_str(v, NULL));
374 printf("type = '%s'\n", buf);
375}
355#endif376#endif
356 377
357/* ------------------------------------------------------------------------- */378/* ------------------------------------------------------------------------- */
@@ -506,7 +527,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, · 148 unmodified lines
506 sym_type = STT_FUNC;527 sym_type = STT_FUNC;
507 } else if ((t & VT_BTYPE) == VT_VOID) {528 } else if ((t & VT_BTYPE) == VT_VOID) {
508 sym_type = STT_NOTYPE;529 sym_type = STT_NOTYPE;
509 if ((t & (VT_BTYPE|VT_ASM_FUNC)) == VT_ASM_FUNC)530 if (IS_ASM_FUNC(t))
510 sym_type = STT_FUNC;531 sym_type = STT_FUNC;
511 } else {532 } else {
512 sym_type = STT_OBJECT;533 sym_type = STT_OBJECT;
@@ -575,8 +596,18 @@ ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, · 62 unmodified lines
575 return;596 return;
576 597
577 if (sym) {598 if (sym) {
578 if (0 == sym->c)599 if (0 == sym->c) {
579 put_extern_sym(sym, NULL, 0, 0);600 put_extern_sym(sym, NULL, 0, 0);
601 if (sym->sym_scope
602 && (sym->type.t & (VT_STATIC|VT_EXTERN)) == (VT_STATIC|VT_EXTERN)) {
603 /* when a local function declaraion redeclares a global static one
604 then tccelf would not resolve them to the same symbol. */
605 Sym *s = sym;
606 while (s->prev_tok)
607 s = s->prev_tok;
608 s->c = sym->c;
609 }
610 }
580 c = sym->c;611 c = sym->c;
581 }612 }
582 613
@@ -683,6 +714,13 @@ ST_INLN Sym *sym_find(int v) · 100 unmodified lines
683 return table_ident[v]->sym_identifier;714 return table_ident[v]->sym_identifier;
684}715}
685 716
717static int sym_scope_e(Sym *s)
718{
719 return IS_ENUM_VAL (s->type.t)
720 ? s->type.ref->sym_scope
721 : s->sym_scope;
722}
723
686/* make sym in-/visible to the parser */724/* make sym in-/visible to the parser */
687static inline void sym_link(Sym *s, int yes)725static inline void sym_link(Sym *s, int yes)
688{726{
@@ -692,10 +730,14 @@ static inline void sym_link(Sym *s, int yes) · 3 unmodified lines
692 ps = &ts->sym_struct;730 ps = &ts->sym_struct;
693 else731 else
694 ps = &ts->sym_identifier;732 ps = &ts->sym_identifier;
695 if (yes)733 if (yes) {
734 if (*ps && sym_scope_e(*ps) == local_scope)
735 tcc_error("redeclaration of '%s'", get_tok_str(s->v, NULL));
696 s->prev_tok = *ps, *ps = s;736 s->prev_tok = *ps, *ps = s;
697 else737 s->sym_scope = local_scope;
738 } else {
698 *ps = s->prev_tok;739 *ps = s->prev_tok;
740 }
699}741}
700 742
701/* push a given symbol on the symbol stack */743/* push a given symbol on the symbol stack */
@@ -710,18 +752,9 @@ ST_FUNC Sym *sym_push(int v, CType *type, int r, int c) · 8 unmodified lines
710 s->type.ref = type->ref;752 s->type.ref = type->ref;
711 s->r = r;753 s->r = r;
712 /* don't record fields or anonymous symbols */754 /* don't record fields or anonymous symbols */
713 /* XXX: simplify */
714 if ((v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {755 if ((v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
715 /* record symbol in token array */756 /* record symbol in token array */
716 sym_link(s, 1);757 sym_link(s, 1);
717 s->sym_scope = local_scope;
718 if (s->prev_tok
719 && (IS_ENUM_VAL (s->prev_tok->type.t)
720 ? s->prev_tok->type.ref->sym_scope
721 : s->prev_tok->sym_scope)
722 == s->sym_scope)
723 tcc_error("redeclaration of '%s'",
724 get_tok_str(v & ~SYM_STRUCT, NULL));
725 }758 }
726 return s;759 return s;
727}760}
@@ -824,19 +857,6 @@ ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep) · 96 unmodified lines
824 *ptop = slast;857 *ptop = slast;
825}858}
826 859
827#if 0
828/* debug: print symbols on stack from s ... last */
829static inline void psyms(const char *msg, Sym *s, Sym *last)
830{
831 printf("%-8s scope v c r type.t\n", msg);
832 while (s && s != last) {
833 printf(" %8x %08x %08x %08x %08x %s\n",
834 s->sym_scope, s->v, s->c, s->r, s->type.t, get_tok_str(s->v, 0));
835 s = s->prev;
836 }
837}
838#endif
839
840/* ------------------------------------------------------------------------- */860/* ------------------------------------------------------------------------- */
841static void vcheck_cmp(void)861static void vcheck_cmp(void)
842{862{
@@ -1294,27 +1314,47 @@ static Sym *sym_copy(Sym *s0, Sym **ps) · 451 unmodified lines
1294 Sym *s;1314 Sym *s;
1295 s = sym_malloc(), *s = *s0;1315 s = sym_malloc(), *s = *s0;
1296 s->prev = *ps, *ps = s;1316 s->prev = *ps, *ps = s;
1297 if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM && ps == &local_stack)1317 if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM)
1298 sym_link(s, 1);1318 sym_link(s, 1);
1299 return s;1319 return s;
1300}1320}
1301 1321
1302/* Symbol 's' was locally declared 'extern' (or as function), and1322/* Symbol 's' was locally declared 'extern' (or as function), and is
1303 is on global_stack. Now must copy its 'ref' to global_stack too */1323 on global_stack. Now must copy its 'ref' to global_stack too */
1304static void sym_copy_ref(Sym *s, Sym **ps)1324static void move_ref_to_global(Sym *s)
1305{1325{
1306 int bt = s->type.t & VT_BTYPE;1326 Sym *l, **lp;
1307 if (bt == VT_PTR1327 int n, bt;
1308 || bt == VT_FUNC1328
1309 || ((bt == VT_STRUCT || IS_ENUM(s->type.t))1329 bt = s->type.t & VT_BTYPE;
1310 && s->type.ref1330 if (!(bt == VT_PTR
1311 && s->type.ref->sym_scope)) {1331 || bt == VT_FUNC
1312 Sym **sp = &s->type.ref;1332 || bt == VT_STRUCT
1313 for (s = *sp, *sp = NULL; s; s = s->next) {1333 || (IS_ENUM(s->type.t)) && (bt = VT_ENUM,1)))
1314 Sym *s2 = sym_copy(s, ps);1334 return;
1315 sp = &(*sp = s2)->next;1335
1316 sym_copy_ref(s2, ps);1336 for (s = s->type.ref, n = 0; s; s = s->next) {
1337 for (lp = &local_stack; !!(l = *lp); lp = &l->prev) {
1338 if (l == s) {
1339 *lp = s->prev;
1340 s->prev = global_stack, global_stack = s;
1341 if (n || bt == VT_PTR) {
1342 move_ref_to_global(s);
1343 } else {
1344 if ((bt == VT_STRUCT || bt == VT_ENUM)
1345 && (s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1346 /* copy struct/enum tag to local scope */
1347 s->v |= SYM_FIELD;
1348 l = sym_copy(s, lp);
1349 l->v &= ~SYM_FIELD;
1350 }
1351 n = 1;
1352 }
1353 break;
1354 }
1317 }1355 }
1356 if (n == 0) /* no next (VT_PTR) or ref not on local_stack */
1357 break;
1318 }1358 }
1319}1359}
1320 1360
@@ -1335,15 +1375,15 @@ static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad) · 14 unmodified lines
1335 s->a = ad->a;1375 s->a = ad->a;
1336 s->asm_label = ad->asm_label;1376 s->asm_label = ad->asm_label;
1337 s->type.ref = type->ref;1377 s->type.ref = type->ref;
1338 /* copy type to the global stack */
1339 if (local_stack)
1340 sym_copy_ref(s, &global_stack);
1341 } else {1378 } else {
1342 patch_storage(s, ad, type);1379 patch_storage(s, ad, type);
1343 }1380 }
1344 /* push variables on local_stack if any */1381 if (local_stack) {
1345 if (local_stack && (s->type.t & VT_BTYPE) != VT_FUNC)1382 /* make sure that type->ref is on global stack */
1383 move_ref_to_global(s);
1384 /* put into local scope */
1346 s = sym_copy(s, &local_stack);1385 s = sym_copy(s, &local_stack);
1386 }
1347 return s;1387 return s;
1348}1388}
1349 1389
@@ -3457,8 +3497,8 @@ ST_FUNC int type_size(CType *type, int *a) · 2107 unmodified lines
3457 int ts;3497 int ts;
3458 s = type->ref;3498 s = type->ref;
3459 ts = type_size(&s->type, a);3499 ts = type_size(&s->type, a);
3460 if (ts < 0 && s->c < 0)3500 if (s->c < 0)
3461 ts = -ts;3501 return s->c;
3462 return ts * s->c;3502 return ts * s->c;
3463 } else {3503 } else {
3464 *a = PTR_SIZE;3504 *a = PTR_SIZE;
@@ -4367,6 +4407,15 @@ static void struct_layout(CType *type, AttributeDef *ad) · 902 unmodified lines
4367 }4407 }
4368}4408}
4369 4409
4410/* Does 'n' fit into integer type 't' ? */
4411static int in_range(long long n, int t)
4412{
4413 unsigned long long m = (1ULL << (btype_size(t & VT_BTYPE) * 8 - 1)) - 1;
4414 if (t & VT_UNSIGNED)
4415 return n <= (m << 1) + 1;
4416 return n >= -(long long)m - 1 && n <= (long long)m;
4417}
4418
4370/* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */4419/* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
4371static void struct_decl(CType *type, int u)4420static void struct_decl(CType *type, int u)
4372{4421{
@@ -4431,36 +4480,26 @@ do_decl: · 58 unmodified lines
4431 /* non empty enums are not allowed */4480 /* non empty enums are not allowed */
4432 ps = &s->next;4481 ps = &s->next;
4433 if (u == VT_ENUM) {4482 if (u == VT_ENUM) {
4434 long long ll = 0, pl = 0, nl = 0, ni = 0, pi = 0;4483 long long ll = 0, pl = 0, nl = 0;
4435 unsigned long long mu = 0;
4436 CType t;4484 CType t;
4437 t.ref = s;4485 t.ref = s;
4486 s->sym_scope = local_scope; /* anonymous symbol won't have set */
4438 /* enum symbols have static storage */4487 /* enum symbols have static storage */
4439 t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;4488 t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
4440 if (bt) {4489 if (bt)
4441 t.t = bt|VT_STATIC|VT_ENUM_VAL;4490 t.t = bt|VT_STATIC|VT_ENUM_VAL;
4442 mu = 1llu << (type_size(&t, &align) * 8 - 1);
4443 pi = mu - 1;
4444 ni = -mu;
4445 mu = (mu << 1) - 1u;
4446 }
4447 for(;;) {4491 for(;;) {
4448 v = tok;4492 v = tok;
4449 if (v < TOK_UIDENT)4493 if (v < TOK_UIDENT)
4450 expect("identifier");4494 expect("identifier");
4451 ss = sym_find(v);
4452 if (ss && !local_stack)
4453 tcc_error("redefinition of enumerator '%s'",
4454 get_tok_str(v, NULL));
4455 next();4495 next();
4456 if (tok == '=') {4496 if (tok == '=') {
4457 next();4497 next();
4458 ll = expr_const64();4498 ll = expr_const64();
4459 }4499 }
4460 if (bt && (t.t & VT_UNSIGNED ? (unsigned long long)ll > mu4500 if (bt && !in_range(ll, t.t))
4461 : ll < ni || ll > pi))4501 tcc_error("enumerator '%s' out of range of its type",
4462 tcc_error("enumerator value outside the range of underlying type '%s'",4502 get_tok_str(v, NULL));
4463 get_tok_str(v, NULL));
4464 ss = sym_push(v, &t, VT_CONST, 0);4503 ss = sym_push(v, &t, VT_CONST, 0);
4465 ss->enum_val = ll;4504 ss->enum_val = ll;
4466 *ps = ss, ps = &ss->next;4505 *ps = ss, ps = &ss->next;
@@ -4626,9 +4665,9 @@ do_decl: · 159 unmodified lines
4626 check_fields(type, 1);4665 check_fields(type, 1);
4627 check_fields(type, 0);4666 check_fields(type, 0);
4628 struct_layout(type, &ad);4667 struct_layout(type, &ad);
4629 if (debug_modes)
4630 tcc_debug_fix_forw(tcc_state, type);
4631 }4668 }
4669 if (debug_modes)
4670 tcc_debug_fix_forw(tcc_state, type);
4632 }4671 }
4633}4672}
4634 4673
@@ -4860,8 +4899,11 @@ static int parse_btype(CType *type, AttributeDef *ad, int ignore_label) · 225 unmodified lines
4860 parse_expr_type(&type1);4899 parse_expr_type(&type1);
4861 /* remove all storage modifiers except typedef */4900 /* remove all storage modifiers except typedef */
4862 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);4901 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
4863 if (type1.ref)4902 if (type1.ref) {
4864 sym_to_attr(ad, type1.ref);4903 sym_to_attr(ad, type1.ref);
4904 if (type1.t & VT_ARRAY)
4905 type1.t |= VT_BT_ARRAY;
4906 }
4865 goto basic_type2;4907 goto basic_type2;
4866 case TOK_THREAD_LOCAL:4908 case TOK_THREAD_LOCAL:
4867 tcc_error("_Thread_local is not implemented");4909 tcc_error("_Thread_local is not implemented");
@@ -4886,12 +4928,12 @@ static int parse_btype(CType *type, AttributeDef *ad, int ignore_label) · 18 unmodified lines
4886 if (t)4928 if (t)
4887 parse_btype_qualify(type, t);4929 parse_btype_qualify(type, t);
4888 t = type->t;4930 t = type->t;
4931 if (t & VT_ARRAY)
4932 t |= VT_BT_ARRAY;
4889 /* get attributes from typedef */4933 /* get attributes from typedef */
4890 sym_to_attr(ad, s);4934 sym_to_attr(ad, s);
4891 typespec_found = 1;4935 typespec_found = 1;
4892 st = bt = -2;4936 st = bt = -2;
4893 if (type->ref && (t & VT_ARRAY) && type->ref->c < 0)
4894 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
4895 break;4937 break;
4896 }4938 }
4897 type_found = 1;4939 type_found = 1;
@@ -4994,15 +5036,15 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 96 unmodified lines
4994 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT | TYPE_PARAM);5036 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT | TYPE_PARAM);
4995 if ((pt.t & VT_BTYPE) == VT_VOID)5037 if ((pt.t & VT_BTYPE) == VT_VOID)
4996 tcc_error("parameter declared as void");5038 tcc_error("parameter declared as void");
4997 if (local_scope > 1 || n == 0)5039 if (n == 0 || (td & TYPE_PARAM))
4998 n = SYM_FIELD;5040 n |= SYM_FIELD;
4999 } else {5041 } else {
5000 n = tok;5042 n = tok;
5001 pt.t = VT_INT | VT_EXTERN; /* default type */5043 pt.t = VT_INT | VT_EXTERN; /* default type */
5002 pt.ref = NULL;5044 pt.ref = NULL;
5003 next();5045 next();
5004 }5046 }
5005 if (local_scope == 1 && n < TOK_UIDENT)5047 if (n < TOK_UIDENT)
5006 expect("identifier");5048 expect("identifier");
5007 convert_parameter_type(&pt);5049 convert_parameter_type(&pt);
5008 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;5050 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
@@ -5026,7 +5068,6 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 17 unmodified lines
5026 /* if no parameters, then old type prototype */5068 /* if no parameters, then old type prototype */
5027 l = FUNC_OLD;5069 l = FUNC_OLD;
5028 skip(')');5070 skip(')');
5029 --local_scope;
5030 /* NOTE: const is ignored in returned type as it has a special5071 /* NOTE: const is ignored in returned type as it has a special
5031 meaning in gcc / C++ */5072 meaning in gcc / C++ */
5032 type->t &= ~VT_CONSTANT; 5073 type->t &= ~VT_CONSTANT;
@@ -5046,10 +5087,9 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 13 unmodified lines
5046 s->next = first;5087 s->next = first;
5047 type->t = VT_FUNC;5088 type->t = VT_FUNC;
5048 type->ref = s;5089 type->ref = s;
5049 5090 /* unlink parameter symbols from the token table, keep on stack */
5050 /* unlink symbols from the token table, keep on stack */
5051 sym_pop(ps, sr, 1);5091 sym_pop(ps, sr, 1);
5052 //psyms("---", *ps, sr);5092 --local_scope;
5053 5093
5054 } else if (tok == '[') {5094 } else if (tok == '[') {
5055 int saved_nocode_wanted = nocode_wanted;5095 int saved_nocode_wanted = nocode_wanted;
@@ -6901,7 +6941,7 @@ static void try_call_scope_cleanup(Sym *stop) · 1845 unmodified lines
6901 Sym *cls = cur_scope->cl.s;6941 Sym *cls = cur_scope->cl.s;
6902 for (; cls != stop; cls = cls->next) {6942 for (; cls != stop; cls = cls->next) {
6903 Sym *fs = cls->cleanup_func;6943 Sym *fs = cls->cleanup_func;
6904 Sym *vs = cls->prev_tok;6944 Sym *vs = cls->cleanup_sym;
6905 save_lvalues();6945 save_lvalues();
6906 vpushsym(&fs->type, fs);6946 vpushsym(&fs->type, fs);
6907 vset(&vs->type, vs->r, vs->c);6947 vset(&vs->type, vs->r, vs->c);
@@ -6912,6 +6952,7 @@ static void try_call_scope_cleanup(Sym *stop) · 4 unmodified lines
6912 }6952 }
6913}6953}
6914 6954
6955
6915static void try_call_cleanup_goto(Sym *cleanupstate)6956static void try_call_cleanup_goto(Sym *cleanupstate)
6916{6957{
6917 Sym *oc, *cc;6958 Sym *oc, *cc;
@@ -6938,7 +6979,7 @@ static void block_cleanup(struct scope *o) · 20 unmodified lines
6938 int jmp = 0;6979 int jmp = 0;
6939 Sym *g, **pg;6980 Sym *g, **pg;
6940 for (pg = &pending_gotos; (g = *pg) && g->c > o->cl.n;) {6981 for (pg = &pending_gotos; (g = *pg) && g->c > o->cl.n;) {
6941 if (g->prev_tok->r & LABEL_FORWARD) {6982 if (g->cleanup_label->r & LABEL_FORWARD) {
6942 Sym *pcl = g->next;6983 Sym *pcl = g->next;
6943 if (!jmp)6984 if (!jmp)
6944 jmp = gjmp(0);6985 jmp = gjmp(0);
@@ -7360,7 +7401,7 @@ again: · 415 unmodified lines
7360 /* start new goto chain for cleanups, linked via label->next */7401 /* start new goto chain for cleanups, linked via label->next */
7361 if (cur_scope->cl.s && !nocode_wanted) {7402 if (cur_scope->cl.s && !nocode_wanted) {
7362 sym_push2(&pending_gotos, SYM_FIELD, 0, cur_scope->cl.n);7403 sym_push2(&pending_gotos, SYM_FIELD, 0, cur_scope->cl.n);
7363 pending_gotos->prev_tok = s;7404 pending_gotos->cleanup_label = s;
7364 s = sym_push2(&s->next, SYM_FIELD, 0, 0);7405 s = sym_push2(&s->next, SYM_FIELD, 0, 0);
7365 pending_gotos->next = s;7406 pending_gotos->next = s;
7366 }7407 }
@@ -7570,7 +7611,7 @@ static void decl_design_flex(init_params *p, Sym *ref, int index) · 203 unmodified lines
7570 if (ref == p->flex_array_ref) {7611 if (ref == p->flex_array_ref) {
7571 if (index >= ref->c)7612 if (index >= ref->c)
7572 ref->c = index + 1;7613 ref->c = index + 1;
7573 } else if (ref->c < 0)7614 } else if (ref->c < 0 && index >= 0)
7574 tcc_error("flexible array has zero size in this context");7615 tcc_error("flexible array has zero size in this context");
7575}7616}
7576 7617
@@ -8029,7 +8070,7 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f · 452 unmodified lines
8029 /* GNU extension: if the initializer is empty for a flex array,8070 /* GNU extension: if the initializer is empty for a flex array,
8030 it's size is zero. We won't enter the loop, so set the size8071 it's size is zero. We won't enter the loop, so set the size
8031 now. */8072 now. */
8032 decl_design_flex(p, s, len);8073 decl_design_flex(p, s, len - 1);
8033 while (tok != '}' || (flags & DIF_HAVE_ELEM)) {8074 while (tok != '}' || (flags & DIF_HAVE_ELEM)) {
8034 len = decl_designator(p, type, c, &f, flags, len);8075 len = decl_designator(p, type, c, &f, flags, len);
8035 flags &= ~DIF_HAVE_ELEM;8076 flags &= ~DIF_HAVE_ELEM;
@@ -8165,6 +8206,13 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 129 unmodified lines
8165 // (arrays of incomplete types are handled in array parsing)8206 // (arrays of incomplete types are handled in array parsing)
8166 if (!(type->t & VT_ARRAY))8207 if (!(type->t & VT_ARRAY))
8167 tcc_error("initialization of incomplete type");8208 tcc_error("initialization of incomplete type");
8209 /* If the base type itself was an array type of unspecified
8210 size (like in 'typedef int arr[]; arr x = {1};') then
8211 we will overwrite the unknown size by the real one for
8212 this decl. We need to unshare the ref symbol holding
8213 that size. */
8214 if (type->t & VT_BT_ARRAY)
8215 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
8168 p.flex_array_ref = type->ref;8216 p.flex_array_ref = type->ref;
8169 8217
8170 } else if (has_init && (type->t & VT_BTYPE) == VT_STRUCT) {8218 } else if (has_init && (type->t & VT_BTYPE) == VT_STRUCT) {
@@ -8182,8 +8230,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 11 unmodified lines
8182 8230
8183 if (size < 0) {8231 if (size < 0) {
8184 /* If unknown size, do a dry-run 1st pass */8232 /* If unknown size, do a dry-run 1st pass */
8185 if (!has_init) 8233 if (!has_init)
8186 tcc_error("unknown type size");8234 goto err_size;
8187 if (has_init == 2) {8235 if (has_init == 2) {
8188 /* only get strings */8236 /* only get strings */
8189 init_str = tok_str_alloc();8237 init_str = tok_str_alloc();
@@ -8206,7 +8254,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 16 unmodified lines
8206 8254
8207 /* if still unknown size, error */8255 /* if still unknown size, error */
8208 size = type_size(type, &align);8256 size = type_size(type, &align);
8209 if (size < 0) 8257 if (size < 0)
8258 err_size:
8210 tcc_error("unknown type size");8259 tcc_error("unknown type size");
8211 8260
8212 /* If there's a flex member and it was used in the initializer8261 /* If there's a flex member and it was used in the initializer
@@ -8258,7 +8307,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 45 unmodified lines
8258 if (ad->cleanup_func) {8307 if (ad->cleanup_func) {
8259 Sym *cls = sym_push2(&all_cleanups,8308 Sym *cls = sym_push2(&all_cleanups,
8260 SYM_FIELD | ++cur_scope->cl.n, 0, 0);8309 SYM_FIELD | ++cur_scope->cl.n, 0, 0);
8261 cls->prev_tok = sym;8310 cls->cleanup_sym = sym;
8262 cls->cleanup_func = ad->cleanup_func;8311 cls->cleanup_func = ad->cleanup_func;
8263 cls->next = cur_scope->cl.s;8312 cls->next = cur_scope->cl.s;
8264 cur_scope->cl.s = cls;8313 cur_scope->cl.s = cls;
@@ -8423,19 +8472,21 @@ ST_FUNC Sym *gfunc_set_param(Sym *s, int c, int byref) · 158 unmodified lines
8423 return NULL;8472 return NULL;
8424 s->c = c;8473 s->c = c;
8425 if (byref)8474 if (byref)
8426 s->r = VT_LLOCAL | VT_LVAL;8475 s->r = VT_LLOCAL | VT_LVAL; /* otherwise VT_LOCAL */
8427 return s;8476 return s;
8428}8477}
8429 8478
8430/* push parameters (and their types), last first */8479/* push parameters (and their types), last first */
8431static void sym_push_params(Sym *ref)8480static void sym_push_params(Sym *ref)
8432{8481{
8433 Sym *s;8482 Sym *s = ref;
8434 for (s = ref; s->next; s = s->next)8483 while (s->next)
8435 ;8484 s = s->next;
8436 for (; s && s != ref; s = s->prev)8485 while (s != ref) {
8437 if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM)8486 if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM)
8438 sym_copy(s, &local_stack);8487 sym_copy(s, &local_stack);
8488 s = s->prev;
8489 }
8439}8490}
8440 8491
8441/* parse a function defined by symbol 'sym' and generate its code in8492/* parse a function defined by symbol 'sym' and generate its code in
@@ -8473,8 +8524,8 @@ static void gen_function(Sym *sym) · 31 unmodified lines
8473 /* push a dummy symbol to enable local sym storage */8524 /* push a dummy symbol to enable local sym storage */
8474 sym_push2(&local_stack, SYM_FIELD, 0, 0);8525 sym_push2(&local_stack, SYM_FIELD, 0, 0);
8475 /* push parameters */8526 /* push parameters */
8527 local_scope = 1;
8476 sym_push_params(sym->type.ref);8528 sym_push_params(sym->type.ref);
8477 //psyms(funcname, local_stack, 0);
8478 8529
8479 local_scope = 0;8530 local_scope = 0;
8480 rsym = 0;8531 rsym = 0;
@@ -8608,7 +8659,7 @@ static int decl(int l) · 127 unmodified lines
8608{8659{
8609 int v, has_init, r, oldint;8660 int v, has_init, r, oldint;
8610 CType type, btype;8661 CType type, btype;
8611 Sym *sym;8662 Sym *sym, *sa;
8612 AttributeDef ad, adbase;8663 AttributeDef ad, adbase;
8613 ElfSym *esym;8664 ElfSym *esym;
8614 8665
@@ -8663,22 +8714,8 @@ static int decl(int l) · 48 unmodified lines
8663 while (1) { /* iterate thru each declaration */8714 while (1) { /* iterate thru each declaration */
8664 type = btype;8715 type = btype;
8665 ad = adbase;8716 ad = adbase;
8666 if ((btype.t & VT_ARRAY) && btype.ref->c < 0) {
8667 /* If the base type itself was an array type of unspecified
8668 size (like in 'typedef int arr[]; arr x = {1};') then
8669 we will overwrite the unknown size by the real one for
8670 this decl. We need to unshare the ref symbol holding
8671 that size. */
8672 type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c);
8673 }
8674 type_decl(&type, &ad, &v, TYPE_DIRECT);8717 type_decl(&type, &ad, &v, TYPE_DIRECT);
8675#if 08718
8676 {
8677 char buf[500];
8678 type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL));
8679 printf("type = '%s'\n", buf);
8680 }
8681#endif
8682 if ((type.t & VT_BTYPE) == VT_FUNC) {8719 if ((type.t & VT_BTYPE) == VT_FUNC) {
8683 if ((type.t & VT_STATIC) && (l != VT_CONST))8720 if ((type.t & VT_STATIC) && (l != VT_CONST))
8684 tcc_error("function without file scope cannot be static");8721 tcc_error("function without file scope cannot be static");
@@ -8722,8 +8759,6 @@ static int decl(int l) · 37 unmodified lines
8722 pe_check_linkage(&type, &ad);8759 pe_check_linkage(&type, &ad);
8723#endif8760#endif
8724 if (tok == '{') {8761 if (tok == '{') {
8725 Sym *sa;
8726
8727 if (l != VT_CONST)8762 if (l != VT_CONST)
8728 tcc_error("cannot use local functions");8763 tcc_error("cannot use local functions");
8729 if ((type.t & VT_BTYPE) != VT_FUNC)8764 if ((type.t & VT_BTYPE) != VT_FUNC)
tests/tests2/129_scopes.c+77−14
@@ -77,40 +77,101 @@ struct st func(void) · 76 unmodified lines
77}77}
78 78
79/* --------------------------------------------- */79/* --------------------------------------------- */
80static void func2(char *(*md)(char *md))80/* func* 'md' must not be shadowed by param 'md' */
81static void f4(char *(*md)(char *md))
81{82{
82 (*md)("test");83 (*md)("test");
83}84}
84 85static char *a4(char *a)
85static char *a(char *a)
86{86{
87 printf("%s\n", a);87 int strcmp();
88 myassert(!strcmp(a, "test"));
88 return a;89 return a;
89}90}
90 91
91int main_4(void)92int main_4()
92{93{
93 func2(a);94 f4(a4);
94 return 0;95 return 0;
95}96}
96 97
97/* --------------------------------------------- */98/* --------------------------------------------- */
98int b[3];99int a5[3], b5[];
99int f(void);100int f5(void);
101int main_5()
102{
103 extern int a5[3], b5[3];
104 a5[2]=10, b5[2]=4;
105 myassert(f5() == 10 + 4);
106 return 0;
107}
108int f5(void)
109{
110 return a5[2]+b5[2];
111}
112int b5[3];
100 113
101int main_5(void)114/* --------------------------------------------- */
115static int f6(int);
116int i6 = 11;
117
118int main_6()
102{119{
103 extern int b[3];120 {
104 b[2]=10;121 int i6 = 33, f6 = 44;
105 printf("%d\n", f());122 myassert(i6 == 33 && f6 == 44);
123 {
124 int f6(int);
125 extern int i6;
126 myassert(i6 == 11 && f6(22) == 22);
127 }
128 myassert(i6 == 33 && f6 == 44);
129 }
130 myassert(i6 == 11 && f6(22) == 22);
106 return 0;131 return 0;
107}132}
108 133
109int f(void)134int f6(int x)
110{135{
111 return b[2]==10 ? 1 : 0;136 return x;
112}137}
113 138
139/* --------------------------------------------- */
140
141#if defined __TINYC__ \
142 ? !defined __leading_underscore \
143 : !(defined __APPLE__ || defined _WIN32)
144# define _
145#else
146# define _ "_"
147#endif
148
149struct xx7 { int a, b; };
150
151void f7()
152{
153 struct xx7 { int c; } x;
154 {
155 extern struct xx7 { int a, b; } x __asm__(_"z7");
156 x.a = 12;
157 struct xx7 y = { 0,0 };
158 }
159 struct xx7 y = { 90 };
160 x.c = 78;
161 printf("xx7 (1) : %d %d\n", x.c, y.c);
162}
163
164int main_7()
165{
166 f7();
167 extern struct xx7 y __asm__(_"z7");
168 printf("xx7 (2) : %d %d\n", y.a, y.b);
169 return 0;
170}
171
172
173struct xx7 z7 = { 0, 34 };
174
114/* --------------------------------------------- */175/* --------------------------------------------- */
115int main()176int main()
116{177{
@@ -119,5 +180,7 @@ int main() · 2 unmodified lines
119 main_3();180 main_3();
120 main_4();181 main_4();
121 main_5();182 main_5();
183 main_6();
184 main_7();
122 return 0;185 return 0;
123}186}
tests/tests2/129_scopes.expect+8−2
@@ -21,5 +21,11 @@ · 20 unmodified lines
21129_scopes.c:43: ok : "!in"21129_scopes.c:43: ok : "!in"
22129_scopes.c:59: ok : "c == 'a'"22129_scopes.c:59: ok : "c == 'a'"
23129_scopes.c:69: ok : "st.a == 10"23129_scopes.c:69: ok : "st.a == 10"
24test24129_scopes.c:88: ok : "!strcmp(a, "test")"
25125129_scopes.c:105: ok : "f5() == 10 + 4"
26129_scopes.c:122: ok : "i6 == 33 && f6 == 44"
27129_scopes.c:126: ok : "i6 == 11 && f6(22) == 22"
28129_scopes.c:128: ok : "i6 == 33 && f6 == 44"
29129_scopes.c:130: ok : "i6 == 11 && f6(22) == 22"
30xx7 (1) : 78 90
31xx7 (2) : 12 34
tests/tests2/35_sizeof.c+24−8
@@ -1,14 +1,30 @@
1#include <stdio.h>1int printf(const char*, ...);
2 2
3int main()3int main()
4{4{
5 char a;5 char a;
6 short b;6 short b;
7 7
8 printf("%d %d\n", sizeof(char), sizeof(a));8 printf("sizeof a : %d %d\n", sizeof(char), sizeof(a));
9 printf("%d %d\n", sizeof(short), sizeof(b));9 printf("sizeof b : %d %d\n", sizeof(short), sizeof(b));
10 10
11 return 0;11 int ii[] = {}; /* gnu extension, size = 0 */
12}12 printf("sizeof ii : %d\n", sizeof ii);
13
14 int kk[] = { 1 };
15 printf("sizeof kk : %d\n", sizeof kk);
16
17 char cc[] = "12";
18 printf("sizeof cc : %d\n", sizeof cc);
13 19
14/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/20 __WCHAR_TYPE__ ll[] = L"12345";
21 printf("len-of ll : %d\n", sizeof ll / sizeof ll[0]);
22
23 static struct {
24 int a,b,c;
25 int d[];
26 } ss[] = {{ 1, 2, 3, {} }};
27 printf("sizeof ss : %d\n", sizeof ss);
28
29 return 0;
30}
tests/tests2/35_sizeof.expect+7−2
@@ -1,2 +1,7 @@
11 11sizeof a : 1 1
22 22sizeof b : 2 2
3sizeof ii : 0
4sizeof kk : 4
5sizeof cc : 3
6len-of ll : 6
7sizeof ss : 12
tests/tests2/39_typedef.c+9−0
@@ -13,6 +13,7 @@ typedef struct FunStruct MyFunStruct; · 12 unmodified lines
13typedef MyFunStruct *MoreFunThanEver;13typedef MyFunStruct *MoreFunThanEver;
14 14
15typedef int t[];15typedef int t[];
16int tints[];
16 17
17int main()18int main()
18{19{
@@ -36,6 +37,14 @@ int main() · 17 unmodified lines
36 printf("%d\n", (int)sizeof((t){1,2,3}));37 printf("%d\n", (int)sizeof((t){1,2,3}));
37 printf("%d\n", (int)sizeof((t){1,2,3,4}));38 printf("%d\n", (int)sizeof((t){1,2,3,4}));
38 39
40 /* two arrays derived from same base type */
41 t t3 = { 1,2,3 }, t4 = { 4,5,6,7 };
42 for (p = t3, i = 0; i < 3 ; i++) printf("%d ", *p++);
43 for (p = t4, i = 0; i < 4 ; i++) printf("%d ", *p++); printf("\n");
44 typeof(tints) t5 = { 1,2,3 }, t6 = { 4,5,6,7 };
45 for (p = t5, i = 0; i < 3 ; i++) printf("%d ", *p++);
46 for (p = t6, i = 0; i < 4 ; i++) printf("%d ", *p++); printf("\n");
47
39 return 0;48 return 0;
40}49}
41 50
tests/tests2/39_typedef.expect+2−0
@@ -5,3 +5,5 @@ · 4 unmodified lines
51 2 3 4 51 2 3 4
612612
716716
81 2 3 4 5 6 7
91 2 3 4 5 6 7
tests/tests2/60_errors_and_warnings.expect+1−1
@@ -17,7 +17,7 @@ · 16 unmodified lines
1760_errors_and_warnings.c:21: error: struct/union/enum already defined1760_errors_and_warnings.c:21: error: struct/union/enum already defined
18 18
19[test_62_enumerator_redefinition]19[test_62_enumerator_redefinition]
2060_errors_and_warnings.c:26: error: redefinition of enumerator 'RED'2060_errors_and_warnings.c:26: error: redeclaration of 'RED'
21 21
22[test_63_local_enumerator_redefinition]22[test_63_local_enumerator_redefinition]
23[returns 1]23[returns 1]

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