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
552552 CType type; /* associated type */
553553 union {
554554 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 */
556556 int asm_label; /* associated asm label */
557557 struct Sym *cleanupstate; /* in defined labels */
558558 int *vla_array_str; /* vla array code */
559559 };
560560 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+ };
562566 } Sym;
563567
564568 /* section definition */
@@ -1074,7 +1078,7 @@ struct filespec { · 509 unmodified lines
10741078
10751079 #define VT_UNION (1 << VT_STRUCT_SHIFT | VT_STRUCT)
10761080 #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 */
10781082
10791083 #define IS_ENUM(t) ((t & VT_STRUCT_MASK) == VT_ENUM)
10801084 #define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL)
@@ -1087,9 +1091,13 @@ struct filespec { · 6 unmodified lines
10871091 #define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))
10881092
10891093 /* symbol was created by tccasm.c first */
1090−#define VT_ASM (VT_VOID | 1 << VT_STRUCT_SHIFT)
1091−#define VT_ASM_FUNC (VT_ASM | 2 << VT_STRUCT_SHIFT)
1092−#define IS_ASM_SYM(sym) (((sym)->type.t & (VT_BTYPE | VT_ASM)) == VT_ASM)
1094+#define VT_ASM (VT_VOID | 4 << VT_STRUCT_SHIFT)
1095+#define VT_ASM_FUNC (VT_VOID | 5 << VT_STRUCT_SHIFT)
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)
10931101
10941102 /* general: set/get the pseudo-bitfield value for bit-mask M */
10951103 #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
842842
843843 if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
844844 if (IS_ASM_SYM(sym))
845− sym->type.t = (sym->type.t & ~VT_ASM) | VT_ASM_FUNC;
845+ sym->type.t |= VT_ASM_FUNC;
846846 st_type = STT_FUNC;
847847 set_st_type:
848848 if (sym->c) {
tccgen.c+145−110
@@ -341,8 +341,8 @@ ST_FUNC void check_vstack(void) · 340 unmodified lines
341341 (int)(vtop - vstack + 1));
342342 }
343343
344−/* vstack debugging aid */
345344 #if 0
345+/* dump 'b' vstack entries starting with 'a' */
346346 void pv (const char *lbl, int a, int b)
347347 {
348348 int i;
@@ -352,6 +352,27 @@ void pv (const char *lbl, int a, int b) · 3 unmodified lines
352352 lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
353353 }
354354 }
355+
356+/* dump symbols on stack from s ... last */
357+static 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+
367+static void type_to_str(char *buf, int buf_size, CType *type, const char *varstr);
368+
369+/* print type */
370+static 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+}
355376 #endif
356377
357378 /* ------------------------------------------------------------------------- */
@@ -506,7 +527,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, · 148 unmodified lines
506527 sym_type = STT_FUNC;
507528 } else if ((t & VT_BTYPE) == VT_VOID) {
508529 sym_type = STT_NOTYPE;
509− if ((t & (VT_BTYPE|VT_ASM_FUNC)) == VT_ASM_FUNC)
530+ if (IS_ASM_FUNC(t))
510531 sym_type = STT_FUNC;
511532 } else {
512533 sym_type = STT_OBJECT;
@@ -575,8 +596,18 @@ ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, · 62 unmodified lines
575596 return;
576597
577598 if (sym) {
578− if (0 == sym->c)
599+ if (0 == sym->c) {
579600 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+ }
580611 c = sym->c;
581612 }
582613
@@ -683,6 +714,13 @@ ST_INLN Sym *sym_find(int v) · 100 unmodified lines
683714 return table_ident[v]->sym_identifier;
684715 }
685716
717+static 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+
686724 /* make sym in-/visible to the parser */
687725 static inline void sym_link(Sym *s, int yes)
688726 {
@@ -692,10 +730,14 @@ static inline void sym_link(Sym *s, int yes) · 3 unmodified lines
692730 ps = &ts->sym_struct;
693731 else
694732 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));
696736 s->prev_tok = *ps, *ps = s;
697− else
737+ s->sym_scope = local_scope;
738+ } else {
698739 *ps = s->prev_tok;
740+ }
699741 }
700742
701743 /* 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
710752 s->type.ref = type->ref;
711753 s->r = r;
712754 /* don't record fields or anonymous symbols */
713− /* XXX: simplify */
714755 if ((v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
715756 /* record symbol in token array */
716757 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));
725758 }
726759 return s;
727760 }
@@ -824,19 +857,6 @@ ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep) · 96 unmodified lines
824857 *ptop = slast;
825858 }
826859
827−#if 0
828−/* debug: print symbols on stack from s ... last */
829−static 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−
840860 /* ------------------------------------------------------------------------- */
841861 static void vcheck_cmp(void)
842862 {
@@ -1294,27 +1314,47 @@ static Sym *sym_copy(Sym *s0, Sym **ps) · 451 unmodified lines
12941314 Sym *s;
12951315 s = sym_malloc(), *s = *s0;
12961316 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)
12981318 sym_link(s, 1);
12991319 return s;
13001320 }
13011321
1302−/* Symbol 's' was locally declared 'extern' (or as function), and
1303− is on global_stack. Now must copy its 'ref' to global_stack too */
1304−static void sym_copy_ref(Sym *s, Sym **ps)
1322+/* Symbol 's' was locally declared 'extern' (or as function), and is
1323+ on global_stack. Now must copy its 'ref' to global_stack too */
1324+static void move_ref_to_global(Sym *s)
13051325 {
1306− int bt = s->type.t & VT_BTYPE;
1307− if (bt == VT_PTR
1308− || bt == VT_FUNC
1309− || ((bt == VT_STRUCT || IS_ENUM(s->type.t))
1310− && s->type.ref
1311− && s->type.ref->sym_scope)) {
1312− Sym **sp = &s->type.ref;
1313− for (s = *sp, *sp = NULL; s; s = s->next) {
1314− Sym *s2 = sym_copy(s, ps);
1315− sp = &(*sp = s2)->next;
1316− sym_copy_ref(s2, ps);
1326+ Sym *l, **lp;
1327+ int n, bt;
1328+
1329+ bt = s->type.t & VT_BTYPE;
1330+ if (!(bt == VT_PTR
1331+ || bt == VT_FUNC
1332+ || bt == VT_STRUCT
1333+ || (IS_ENUM(s->type.t)) && (bt = VT_ENUM,1)))
1334+ return;
1335+
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+ }
13171355 }
1356+ if (n == 0) /* no next (VT_PTR) or ref not on local_stack */
1357+ break;
13181358 }
13191359 }
13201360
@@ -1335,15 +1375,15 @@ static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad) · 14 unmodified lines
13351375 s->a = ad->a;
13361376 s->asm_label = ad->asm_label;
13371377 s->type.ref = type->ref;
1338− /* copy type to the global stack */
1339− if (local_stack)
1340− sym_copy_ref(s, &global_stack);
13411378 } else {
13421379 patch_storage(s, ad, type);
13431380 }
1344− /* push variables on local_stack if any */
1345− if (local_stack && (s->type.t & VT_BTYPE) != VT_FUNC)
1381+ if (local_stack) {
1382+ /* make sure that type->ref is on global stack */
1383+ move_ref_to_global(s);
1384+ /* put into local scope */
13461385 s = sym_copy(s, &local_stack);
1386+ }
13471387 return s;
13481388 }
13491389
@@ -3457,8 +3497,8 @@ ST_FUNC int type_size(CType *type, int *a) · 2107 unmodified lines
34573497 int ts;
34583498 s = type->ref;
34593499 ts = type_size(&s->type, a);
3460− if (ts < 0 && s->c < 0)
3461− ts = -ts;
3500+ if (s->c < 0)
3501+ return s->c;
34623502 return ts * s->c;
34633503 } else {
34643504 *a = PTR_SIZE;
@@ -4367,6 +4407,15 @@ static void struct_layout(CType *type, AttributeDef *ad) · 902 unmodified lines
43674407 }
43684408 }
43694409
4410+/* Does 'n' fit into integer type 't' ? */
4411+static 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+
43704419 /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
43714420 static void struct_decl(CType *type, int u)
43724421 {
@@ -4431,36 +4480,26 @@ do_decl: · 58 unmodified lines
44314480 /* non empty enums are not allowed */
44324481 ps = &s->next;
44334482 if (u == VT_ENUM) {
4434− long long ll = 0, pl = 0, nl = 0, ni = 0, pi = 0;
4435− unsigned long long mu = 0;
4483+ long long ll = 0, pl = 0, nl = 0;
44364484 CType t;
44374485 t.ref = s;
4486+ s->sym_scope = local_scope; /* anonymous symbol won't have set */
44384487 /* enum symbols have static storage */
44394488 t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
4440− if (bt) {
4489+ if (bt)
44414490 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− }
44474491 for(;;) {
44484492 v = tok;
44494493 if (v < TOK_UIDENT)
44504494 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));
44554495 next();
44564496 if (tok == '=') {
44574497 next();
44584498 ll = expr_const64();
44594499 }
4460− if (bt && (t.t & VT_UNSIGNED ? (unsigned long long)ll > mu
4461− : ll < ni || ll > pi))
4462− tcc_error("enumerator value outside the range of underlying type '%s'",
4463− get_tok_str(v, NULL));
4500+ if (bt && !in_range(ll, t.t))
4501+ tcc_error("enumerator '%s' out of range of its type",
4502+ get_tok_str(v, NULL));
44644503 ss = sym_push(v, &t, VT_CONST, 0);
44654504 ss->enum_val = ll;
44664505 *ps = ss, ps = &ss->next;
@@ -4626,9 +4665,9 @@ do_decl: · 159 unmodified lines
46264665 check_fields(type, 1);
46274666 check_fields(type, 0);
46284667 struct_layout(type, &ad);
4629− if (debug_modes)
4630− tcc_debug_fix_forw(tcc_state, type);
46314668 }
4669+ if (debug_modes)
4670+ tcc_debug_fix_forw(tcc_state, type);
46324671 }
46334672 }
46344673
@@ -4860,8 +4899,11 @@ static int parse_btype(CType *type, AttributeDef *ad, int ignore_label) · 225 unmodified lines
48604899 parse_expr_type(&type1);
48614900 /* remove all storage modifiers except typedef */
48624901 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
4863− if (type1.ref)
4902+ if (type1.ref) {
48644903 sym_to_attr(ad, type1.ref);
4904+ if (type1.t & VT_ARRAY)
4905+ type1.t |= VT_BT_ARRAY;
4906+ }
48654907 goto basic_type2;
48664908 case TOK_THREAD_LOCAL:
48674909 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
48864928 if (t)
48874929 parse_btype_qualify(type, t);
48884930 t = type->t;
4931+ if (t & VT_ARRAY)
4932+ t |= VT_BT_ARRAY;
48894933 /* get attributes from typedef */
48904934 sym_to_attr(ad, s);
48914935 typespec_found = 1;
48924936 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);
48954937 break;
48964938 }
48974939 type_found = 1;
@@ -4994,15 +5036,15 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 96 unmodified lines
49945036 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT | TYPE_PARAM);
49955037 if ((pt.t & VT_BTYPE) == VT_VOID)
49965038 tcc_error("parameter declared as void");
4997− if (local_scope > 1 || n == 0)
4998− n = SYM_FIELD;
5039+ if (n == 0 || (td & TYPE_PARAM))
5040+ n |= SYM_FIELD;
49995041 } else {
50005042 n = tok;
50015043 pt.t = VT_INT | VT_EXTERN; /* default type */
50025044 pt.ref = NULL;
50035045 next();
50045046 }
5005− if (local_scope == 1 && n < TOK_UIDENT)
5047+ if (n < TOK_UIDENT)
50065048 expect("identifier");
50075049 convert_parameter_type(&pt);
50085050 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
50265068 /* if no parameters, then old type prototype */
50275069 l = FUNC_OLD;
50285070 skip(')');
5029− --local_scope;
50305071 /* NOTE: const is ignored in returned type as it has a special
50315072 meaning in gcc / C++ */
50325073 type->t &= ~VT_CONSTANT;
@@ -5046,10 +5087,9 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 13 unmodified lines
50465087 s->next = first;
50475088 type->t = VT_FUNC;
50485089 type->ref = s;
5049−
5050− /* unlink symbols from the token table, keep on stack */
5090+ /* unlink parameter symbols from the token table, keep on stack */
50515091 sym_pop(ps, sr, 1);
5052− //psyms("---", *ps, sr);
5092+ --local_scope;
50535093
50545094 } else if (tok == '[') {
50555095 int saved_nocode_wanted = nocode_wanted;
@@ -6901,7 +6941,7 @@ static void try_call_scope_cleanup(Sym *stop) · 1845 unmodified lines
69016941 Sym *cls = cur_scope->cl.s;
69026942 for (; cls != stop; cls = cls->next) {
69036943 Sym *fs = cls->cleanup_func;
6904− Sym *vs = cls->prev_tok;
6944+ Sym *vs = cls->cleanup_sym;
69056945 save_lvalues();
69066946 vpushsym(&fs->type, fs);
69076947 vset(&vs->type, vs->r, vs->c);
@@ -6912,6 +6952,7 @@ static void try_call_scope_cleanup(Sym *stop) · 4 unmodified lines
69126952 }
69136953 }
69146954
6955+
69156956 static void try_call_cleanup_goto(Sym *cleanupstate)
69166957 {
69176958 Sym *oc, *cc;
@@ -6938,7 +6979,7 @@ static void block_cleanup(struct scope *o) · 20 unmodified lines
69386979 int jmp = 0;
69396980 Sym *g, **pg;
69406981 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) {
69426983 Sym *pcl = g->next;
69436984 if (!jmp)
69446985 jmp = gjmp(0);
@@ -7360,7 +7401,7 @@ again: · 415 unmodified lines
73607401 /* start new goto chain for cleanups, linked via label->next */
73617402 if (cur_scope->cl.s && !nocode_wanted) {
73627403 sym_push2(&pending_gotos, SYM_FIELD, 0, cur_scope->cl.n);
7363− pending_gotos->prev_tok = s;
7404+ pending_gotos->cleanup_label = s;
73647405 s = sym_push2(&s->next, SYM_FIELD, 0, 0);
73657406 pending_gotos->next = s;
73667407 }
@@ -7570,7 +7611,7 @@ static void decl_design_flex(init_params *p, Sym *ref, int index) · 203 unmodified lines
75707611 if (ref == p->flex_array_ref) {
75717612 if (index >= ref->c)
75727613 ref->c = index + 1;
7573− } else if (ref->c < 0)
7614+ } else if (ref->c < 0 && index >= 0)
75747615 tcc_error("flexible array has zero size in this context");
75757616 }
75767617
@@ -8029,7 +8070,7 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f · 452 unmodified lines
80298070 /* GNU extension: if the initializer is empty for a flex array,
80308071 it's size is zero. We won't enter the loop, so set the size
80318072 now. */
8032− decl_design_flex(p, s, len);
8073+ decl_design_flex(p, s, len - 1);
80338074 while (tok != '}' || (flags & DIF_HAVE_ELEM)) {
80348075 len = decl_designator(p, type, c, &f, flags, len);
80358076 flags &= ~DIF_HAVE_ELEM;
@@ -8165,6 +8206,13 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 129 unmodified lines
81658206 // (arrays of incomplete types are handled in array parsing)
81668207 if (!(type->t & VT_ARRAY))
81678208 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);
81688216 p.flex_array_ref = type->ref;
81698217
81708218 } 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
81828230
81838231 if (size < 0) {
81848232 /* If unknown size, do a dry-run 1st pass */
8185− if (!has_init)
8186− tcc_error("unknown type size");
8233+ if (!has_init)
8234+ goto err_size;
81878235 if (has_init == 2) {
81888236 /* only get strings */
81898237 init_str = tok_str_alloc();
@@ -8206,7 +8254,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 16 unmodified lines
82068254
82078255 /* if still unknown size, error */
82088256 size = type_size(type, &align);
8209− if (size < 0)
8257+ if (size < 0)
8258+ err_size:
82108259 tcc_error("unknown type size");
82118260
82128261 /* 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
82588307 if (ad->cleanup_func) {
82598308 Sym *cls = sym_push2(&all_cleanups,
82608309 SYM_FIELD | ++cur_scope->cl.n, 0, 0);
8261− cls->prev_tok = sym;
8310+ cls->cleanup_sym = sym;
82628311 cls->cleanup_func = ad->cleanup_func;
82638312 cls->next = cur_scope->cl.s;
82648313 cur_scope->cl.s = cls;
@@ -8423,19 +8472,21 @@ ST_FUNC Sym *gfunc_set_param(Sym *s, int c, int byref) · 158 unmodified lines
84238472 return NULL;
84248473 s->c = c;
84258474 if (byref)
8426− s->r = VT_LLOCAL | VT_LVAL;
8475+ s->r = VT_LLOCAL | VT_LVAL; /* otherwise VT_LOCAL */
84278476 return s;
84288477 }
84298478
84308479 /* push parameters (and their types), last first */
84318480 static void sym_push_params(Sym *ref)
84328481 {
8433− Sym *s;
8434− for (s = ref; s->next; s = s->next)
8435− ;
8436− for (; s && s != ref; s = s->prev)
8482+ Sym *s = ref;
8483+ while (s->next)
8484+ s = s->next;
8485+ while (s != ref) {
84378486 if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM)
84388487 sym_copy(s, &local_stack);
8488+ s = s->prev;
8489+ }
84398490 }
84408491
84418492 /* 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
84738524 /* push a dummy symbol to enable local sym storage */
84748525 sym_push2(&local_stack, SYM_FIELD, 0, 0);
84758526 /* push parameters */
8527+ local_scope = 1;
84768528 sym_push_params(sym->type.ref);
8477− //psyms(funcname, local_stack, 0);
84788529
84798530 local_scope = 0;
84808531 rsym = 0;
@@ -8608,7 +8659,7 @@ static int decl(int l) · 127 unmodified lines
86088659 {
86098660 int v, has_init, r, oldint;
86108661 CType type, btype;
8611− Sym *sym;
8662+ Sym *sym, *sa;
86128663 AttributeDef ad, adbase;
86138664 ElfSym *esym;
86148665
@@ -8663,22 +8714,8 @@ static int decl(int l) · 48 unmodified lines
86638714 while (1) { /* iterate thru each declaration */
86648715 type = btype;
86658716 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− }
86748717 type_decl(&type, &ad, &v, TYPE_DIRECT);
8675−#if 0
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
8718+
86828719 if ((type.t & VT_BTYPE) == VT_FUNC) {
86838720 if ((type.t & VT_STATIC) && (l != VT_CONST))
86848721 tcc_error("function without file scope cannot be static");
@@ -8722,8 +8759,6 @@ static int decl(int l) · 37 unmodified lines
87228759 pe_check_linkage(&type, &ad);
87238760 #endif
87248761 if (tok == '{') {
8725− Sym *sa;
8726−
87278762 if (l != VT_CONST)
87288763 tcc_error("cannot use local functions");
87298764 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
7777 }
7878
7979 /* --------------------------------------------- */
80−static void func2(char *(*md)(char *md))
80+/* func* 'md' must not be shadowed by param 'md' */
81+static void f4(char *(*md)(char *md))
8182 {
8283 (*md)("test");
8384 }
84−
85−static char *a(char *a)
85+static char *a4(char *a)
8686 {
87− printf("%s\n", a);
87+ int strcmp();
88+ myassert(!strcmp(a, "test"));
8889 return a;
8990 }
9091
91−int main_4(void)
92+int main_4()
9293 {
93− func2(a);
94+ f4(a4);
9495 return 0;
9596 }
9697
9798 /* --------------------------------------------- */
98−int b[3];
99−int f(void);
99+int a5[3], b5[];
100+int f5(void);
101+int 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+}
108+int f5(void)
109+{
110+ return a5[2]+b5[2];
111+}
112+int b5[3];
100113
101−int main_5(void)
114+/* --------------------------------------------- */
115+static int f6(int);
116+int i6 = 11;
117+
118+int main_6()
102119 {
103− extern int b[3];
104− b[2]=10;
105− printf("%d\n", f());
120+ {
121+ int i6 = 33, f6 = 44;
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);
106131 return 0;
107132 }
108133
109−int f(void)
134+int f6(int x)
110135 {
111− return b[2]==10 ? 1 : 0;
136+ return x;
112137 }
113138
139+/* --------------------------------------------- */
140+
141+#if defined __TINYC__ \
142+ ? !defined __leading_underscore \
143+ : !(defined __APPLE__ || defined _WIN32)
144+# define _
145+#else
146+# define _ "_"
147+#endif
148+
149+struct xx7 { int a, b; };
150+
151+void 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+
164+int 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+
173+struct xx7 z7 = { 0, 34 };
174+
114175 /* --------------------------------------------- */
115176 int main()
116177 {
@@ -119,5 +180,7 @@ int main() · 2 unmodified lines
119180 main_3();
120181 main_4();
121182 main_5();
183+ main_6();
184+ main_7();
122185 return 0;
123186 }
tests/tests2/129_scopes.expect+8−2
@@ -21,5 +21,11 @@ · 20 unmodified lines
2121 129_scopes.c:43: ok : "!in"
2222 129_scopes.c:59: ok : "c == 'a'"
2323 129_scopes.c:69: ok : "st.a == 10"
24−test
25−1
24+129_scopes.c:88: ok : "!strcmp(a, "test")"
25+129_scopes.c:105: ok : "f5() == 10 + 4"
26+129_scopes.c:122: ok : "i6 == 33 && f6 == 44"
27+129_scopes.c:126: ok : "i6 == 11 && f6(22) == 22"
28+129_scopes.c:128: ok : "i6 == 33 && f6 == 44"
29+129_scopes.c:130: ok : "i6 == 11 && f6(22) == 22"
30+xx7 (1) : 78 90
31+xx7 (2) : 12 34
tests/tests2/35_sizeof.c+24−8
@@ -1,14 +1,30 @@
1−#include <stdio.h>
1+int printf(const char*, ...);
22
33 int main()
44 {
5− char a;
6− short b;
5+ char a;
6+ short b;
77
8− printf("%d %d\n", sizeof(char), sizeof(a));
9− printf("%d %d\n", sizeof(short), sizeof(b));
8+ printf("sizeof a : %d %d\n", sizeof(char), sizeof(a));
9+ printf("sizeof b : %d %d\n", sizeof(short), sizeof(b));
1010
11− return 0;
12−}
11+ int ii[] = {}; /* gnu extension, size = 0 */
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);
1319
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 @@
1−1 1
2−2 2
1+sizeof a : 1 1
2+sizeof b : 2 2
3+sizeof ii : 0
4+sizeof kk : 4
5+sizeof cc : 3
6+len-of ll : 6
7+sizeof ss : 12
tests/tests2/39_typedef.c+9−0
@@ -13,6 +13,7 @@ typedef struct FunStruct MyFunStruct; · 12 unmodified lines
1313 typedef MyFunStruct *MoreFunThanEver;
1414
1515 typedef int t[];
16+int tints[];
1617
1718 int main()
1819 {
@@ -36,6 +37,14 @@ int main() · 17 unmodified lines
3637 printf("%d\n", (int)sizeof((t){1,2,3}));
3738 printf("%d\n", (int)sizeof((t){1,2,3,4}));
3839
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+
3948 return 0;
4049 }
4150
tests/tests2/39_typedef.expect+2−0
@@ -5,3 +5,5 @@ · 4 unmodified lines
55 1 2 3 4
66 12
77 16
8+1 2 3 4 5 6 7
9+1 2 3 4 5 6 7
tests/tests2/60_errors_and_warnings.expect+1−1
@@ -17,7 +17,7 @@ · 16 unmodified lines
1717 60_errors_and_warnings.c:21: error: struct/union/enum already defined
1818
1919 [test_62_enumerator_redefinition]
20−60_errors_and_warnings.c:26: error: redefinition of enumerator 'RED'
20+60_errors_and_warnings.c:26: error: redeclaration of 'RED'
2121
2222 [test_63_local_enumerator_redefinition]
2323 [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