History

tccgen.c: fix two scope problems

... see tests

grischka committed 1 year ago

Commit acb2a901 parent 4e6c4db8 files · +165 −59Browse files

Unified · Split

8 files
  1. arm-link.c +9 −8
  2. libtcc.c +3 −4
  3. tcc.c +2 −3
  4. tcc.h +4 −4
  5. tccdbg.c +66 −27
  6. tccgen.c +12 −10
  7. tests/tests2/129_scopes.c +46 −3
  8. tests/tests2/129_scopes.expect +23 −0
arm-link.c+9−8
@@ -194,17 +194,18 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 193 unmodified lines
194194 case R_ARM_PLT32:
195195 {
196196 int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
197− x = read32le(ptr) & 0xffffff;
197+ unsigned code = read32le(ptr);
198+ x = code & 0x00ffffff;
198199 #ifdef DEBUG_RELOC
199200 printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
200201 #endif
201− write32le(ptr, read32le(ptr) & 0xff000000);
202− if (x & 0x800000)
203− x -= 0x1000000;
204− x = (unsigned) x << 2;
202+ code &= 0xff000000;
203+ x <<= 2;
204+ if (x & 0x2000000)
205+ x -= 0x4000000;
205206 blx_avail = (CONFIG_TCC_CPUVER >= 5);
206207 is_thumb = val & 1;
207− is_bl = read32le(ptr) >> 24 == 0xeb;
208+ is_bl = code == 0xeb000000;
208209 is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
209210 x += val - addr;
210211 #ifdef DEBUG_RELOC
@@ -220,9 +221,9 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 9 unmodified lines
220221 /* Only reached if blx is avail and it is a call */
221222 if (is_thumb) {
222223 x |= h << 24;
223− write32le(ptr, 0xfa << 24); /* bl -> blx */
224+ code = 0xfa000000; /* bl -> blx */
224225 }
225− write32le(ptr, read32le(ptr) | x);
226+ write32le(ptr, code | x);
226227 }
227228 return;
228229 /* Since these relocations only concern Thumb-2 and blx instruction was
libtcc.c+3−4
@@ -326,7 +326,7 @@ struct mem_debug_header { · 325 unmodified lines
326326 struct mem_debug_header *prev;
327327 struct mem_debug_header *next;
328328 int line_num;
329− char file_name[MEM_DEBUG_FILE_LEN + 1];
329+ char file_name[MEM_DEBUG_FILE_LEN];
330330 unsigned magic2;
331331 ALIGNED(16) unsigned char magic3[4];
332332 };
@@ -367,9 +367,8 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) · 34 unmodified lines
367367 header->size = size;
368368 write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3);
369369 header->line_num = line;
370− ofs = strlen(file) - MEM_DEBUG_FILE_LEN;
371− strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN);
372− header->file_name[MEM_DEBUG_FILE_LEN] = 0;
370+ ofs = strlen(file) + 1 - MEM_DEBUG_FILE_LEN;
371+ strcpy(header->file_name, file + (ofs > 0 ? ofs : 0));
373372 WAIT_SEM(&mem_sem);
374373 header->next = mem_debug_chain;
375374 header->prev = NULL;
tcc.c+2−3
@@ -323,13 +323,12 @@ redo: · 322 unmodified lines
323323 tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
324324 print_search_dirs(s);
325325 }
326− if (opt < 0) err:
327− ret = 1, opt = -1;
328326 if (opt) {
327+ if (opt < 0) err:
328+ ret = 1;
329329 tcc_delete(s);
330330 return ret;
331331 }
332−
333332 if (s->nb_files == 0) {
334333 tcc_error_noabort("no input files");
335334 } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
tcc.h+4−4
@@ -95,13 +95,13 @@ extern long double strtold (const char *__nptr, char **__endptr); · 94 unmodified lines
9595 # define O_BINARY 0
9696 #endif
9797
98+#ifndef offsetof
9899 #ifdef __clang__ // clang -fsanitize compains about: NULL+value
99100 #define offsetof(type, field) __builtin_offsetof(type, field)
100−#endif
101−
102−#ifndef offsetof
101+#else
103102 #define offsetof(type, field) ((size_t) &((type *)0)->field)
104103 #endif
104+#endif
105105
106106 #ifndef countof
107107 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
@@ -1074,7 +1074,7 @@ struct filespec { · 966 unmodified lines
10741074
10751075 #define VT_UNION (1 << VT_STRUCT_SHIFT | VT_STRUCT)
10761076 #define VT_ENUM (2 << VT_STRUCT_SHIFT) /* integral type is an enum really */
1077−#define VT_ENUM_VAL (3 << VT_STRUCT_SHIFT) /* integral type is an enum constant really */
1077+#define VT_ENUM_VAL (4 << VT_STRUCT_SHIFT) /* integral type is an enum constant really */
10781078
10791079 #define IS_ENUM(t) ((t & VT_STRUCT_MASK) == VT_ENUM)
10801080 #define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL)
tccdbg.c+66−27
@@ -1675,16 +1675,20 @@ static void tcc_debug_check_forw(TCCState *s1, Sym *t, int debug_type) · 1674 unmodified lines
16751675 }
16761676 }
16771677
1678+static void stabs_struct_complete(TCCState *s1, CType *t);
1679+
16781680 ST_FUNC void tcc_debug_fix_forw(TCCState *s1, CType *t)
16791681 {
16801682 if (!(s1->do_debug & 2))
16811683 return;
1682−
1684+ if (0 == s1->dwarf) {
1685+ stabs_struct_complete(s1, t);
1686+ return;
1687+ }
16831688 if ((t->t & VT_BTYPE) == VT_STRUCT && t->ref->c != -1) {
16841689 int i, j, debug_type, g = check_global(t->ref);
16851690 int *n_forw_hash;
16861691 struct _debug_forw_hash **forw_hash;
1687−
16881692 forw_hash = g ? &debug_forw_hash_global : &debug_forw_hash_local;
16891693 n_forw_hash = g ? &n_debug_forw_hash_global : &n_debug_forw_hash_local;
16901694 for (i = 0; i < *n_forw_hash; i++)
@@ -1722,14 +1726,46 @@ static int tcc_debug_add(TCCState *s1, Sym *t, int dwarf) · 31 unmodified lines
17221726 return offset;
17231727 }
17241728
1725−#define STRUCT_NODEBUG(s) \
1726− (s->a.nodebug || \
1727− ((s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM && \
1728− ((s->type.t & VT_BTYPE) == VT_BYTE || \
1729− (s->type.t & VT_BTYPE) == VT_BOOL || \
1730− (s->type.t & VT_BTYPE) == VT_SHORT || \
1731− (s->type.t & VT_BTYPE) == VT_INT || \
1732− (s->type.t & VT_BTYPE) == VT_LLONG)))
1729+static int STRUCT_NODEBUG(Sym *s)
1730+{
1731+ return
1732+ (s->a.nodebug ||
1733+ ((s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM &&
1734+ ((s->type.t & VT_BTYPE) == VT_BYTE ||
1735+ (s->type.t & VT_BTYPE) == VT_BOOL ||
1736+ (s->type.t & VT_BTYPE) == VT_SHORT ||
1737+ (s->type.t & VT_BTYPE) == VT_INT ||
1738+ (s->type.t & VT_BTYPE) == VT_LLONG)));
1739+}
1740+
1741+static int stabs_struct_find(TCCState *s1, Sym *t, int *p_id)
1742+{
1743+ /* A struct/enum has a ref to its type but that type has no ref.
1744+ So we can (ab)use it for some info. Here:
1745+ s->c : stabs type id
1746+ s->r : already defined in stabs */
1747+ Sym *s = t->type.ref;
1748+/*
1749+ if (s && s->v != (SYM_FIELD|0x00DEBBED)) {
1750+ tcc_error_noabort("tccdbg: internal error: %s", get_tok_str(t->v, 0));
1751+ if (p_id)
1752+ *p_id = 0;
1753+ return 0;
1754+ }
1755+*/
1756+ if (NULL == p_id)
1757+ return s && !s->r && t->c >= 0;
1758+ if (NULL == s) {
1759+ /* just use global_stack always */
1760+ s = sym_push2(&global_stack, SYM_FIELD|0x00DEBBED, 0, ++debug_next_type);
1761+ t->type.ref = s;
1762+ }
1763+ *p_id = s->c;
1764+ if (s->r || t->c < 0) /* already defined or still incomplete */
1765+ return 0;
1766+ s->r = 1;
1767+ return 1;
1768+}
17331769
17341770 static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result)
17351771 {
@@ -1750,9 +1786,7 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 14 unmodified lines
17501786 }
17511787 if ((type & VT_BTYPE) == VT_STRUCT) {
17521788 t = t->type.ref;
1753− debug_type = tcc_debug_find(s1, t, 0);
1754− if (debug_type == -1) {
1755− debug_type = tcc_debug_add(s1, t, 0);
1789+ if (stabs_struct_find(s1, t, &debug_type)) {
17561790 cstr_new (&str);
17571791 cstr_printf (&str, "%s:T%d=%c%d",
17581792 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
@@ -1760,15 +1794,16 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 1 unmodified line
17601794 debug_type,
17611795 IS_UNION (t->type.t) ? 'u' : 's',
17621796 t->c);
1797+
17631798 while (t->next) {
17641799 int pos, size, align;
1765−
17661800 t = t->next;
17671801 if (STRUCT_NODEBUG(t))
17681802 continue;
1769− tcc_debug_check_forw(s1, t, -1);
17701803 cstr_printf (&str, "%s:",
1771− get_tok_str(t->v, NULL));
1804+ (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1805+ ? "" : get_tok_str(t->v, NULL)
1806+ );
17721807 tcc_get_debug_info (s1, t, &str);
17731808 if (t->type.t & VT_BITFIELD) {
17741809 pos = t->c * 8 + BIT_POS(t->type.t);
@@ -1787,10 +1822,7 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 12 unmodified lines
17871822 }
17881823 else if (IS_ENUM(type)) {
17891824 Sym *e = t = t->type.ref;
1790−
1791− debug_type = tcc_debug_find(s1, t, 0);
1792− if (debug_type == -1) {
1793− debug_type = tcc_debug_add(s1, t, 0);
1825+ if (stabs_struct_find(s1, t, &debug_type)) {
17941826 cstr_new (&str);
17951827 cstr_printf (&str, "%s:T%d=e",
17961828 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
@@ -1817,6 +1849,10 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 20 unmodified lines
18171849 if (debug_type > N_DEFAULT_DEBUG)
18181850 return;
18191851 }
1852+
1853+ if (NULL == result) /* from stabs_struct_complete() */
1854+ return;
1855+
18201856 if (n > 0)
18211857 cstr_printf (result, "%d=", ++debug_next_type);
18221858 t = s;
@@ -1836,12 +1872,19 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 13 unmodified lines
18361872 }
18371873 else
18381874 break;
1839− tcc_debug_check_forw(s1, t, -1);
18401875 t = t->type.ref;
18411876 }
18421877 cstr_printf (result, "%d", debug_type);
18431878 }
18441879
1880+static void stabs_struct_complete(TCCState *s1, CType *t)
1881+{
1882+ if (stabs_struct_find(s1, t->ref, NULL)) {
1883+ Sym s = {0}; s.type = *t;
1884+ tcc_get_debug_info(s1, &s, NULL);
1885+ }
1886+}
1887+
18451888 static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
18461889 {
18471890 int type;
@@ -1993,7 +2036,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 145 unmodified lines
19932036 dwarf_data1(dwarf_info_section, DWARF_ABBREV_BASE_TYPE);
19942037 dwarf_uleb128(dwarf_info_section, default_debug[i - 1].size);
19952038 dwarf_data1(dwarf_info_section, default_debug[i - 1].encoding);
1996− strncpy(name, default_debug[i - 1].name, sizeof(name) -1);
2039+ pstrcpy(name, sizeof name, default_debug[i - 1].name);
19972040 *strchr(name, ':') = 0;
19982041 dwarf_strp(dwarf_info_section, name);
19992042 dwarf_info.base_type_used[i - 1] = debug_type;
@@ -2404,7 +2447,6 @@ ST_FUNC void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bi · 404 unmodified lines
24042447 sym_bind == STB_GLOBAL ? 'G' : func_ind != -1 ? 'V' : 'S'
24052448 );
24062449 tcc_get_debug_info(s1, sym, &str);
2407− tcc_debug_check_forw(s1, sym, -1);
24082450 if (sym_bind == STB_GLOBAL)
24092451 tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0, 0);
24102452 else
@@ -2437,11 +2479,8 @@ ST_FUNC void tcc_debug_typedef(TCCState *s1, Sym *sym) · 26 unmodified lines
24372479 {
24382480 CString str;
24392481 cstr_new (&str);
2440− cstr_printf (&str, "%s:t",
2441− (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
2442− ? "" : get_tok_str(sym->v, NULL));
2482+ cstr_printf (&str, "%s:t", get_tok_str(sym->v, NULL));
24432483 tcc_get_debug_info(s1, sym, &str);
2444− tcc_debug_check_forw(s1, sym, -1);
24452484 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
24462485 cstr_free (&str);
24472486 }
tccgen.c+12−10
@@ -1294,16 +1294,21 @@ static Sym *sym_copy(Sym *s0, Sym **ps) · 1293 unmodified lines
12941294 Sym *s;
12951295 s = sym_malloc(), *s = *s0;
12961296 s->prev = *ps, *ps = s;
1297− if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM)
1297+ if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM && ps == &local_stack)
12981298 sym_link(s, 1);
12991299 return s;
13001300 }
13011301
1302−/* copy s->type.ref to stack 'ps' for VT_FUNC and VT_PTR */
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 */
13031304 static void sym_copy_ref(Sym *s, Sym **ps)
13041305 {
13051306 int bt = s->type.t & VT_BTYPE;
1306− if (bt == VT_FUNC || bt == VT_PTR || (bt == VT_STRUCT && s->sym_scope)) {
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)) {
13071312 Sym **sp = &s->type.ref;
13081313 for (s = *sp, *sp = NULL; s; s = s->next) {
13091314 Sym *s2 = sym_copy(s, ps);
@@ -5962,13 +5967,10 @@ ST_FUNC void unary(void) · 4652 unmodified lines
59625967 learn = 1;
59635968 next();
59645969 } else {
5965− AttributeDef ad_tmp;
5966− int itmp;
5967− CType cur_type;
5968−
5969− parse_btype(&cur_type, &ad_tmp, 0);
5970− type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
5971− if (compare_types(&controlling_type, &cur_type, 0)) {
5970+ int v;
5971+ parse_btype(&type, &ad, 0);
5972+ type_decl(&type, &ad, &v, TYPE_ABSTRACT);
5973+ if (compare_types(&controlling_type, &type, 0)) {
59725974 if (has_match) {
59735975 tcc_error("type match twice");
59745976 }
tests/tests2/129_scopes.c+46−3
@@ -1,7 +1,11 @@
1−#include <stdio.h>
1+int printf(const char*, ...);
2+
3+#define myassert(x) \
4+ printf("%s:%d: %s : \"%s\"\n", __FILE__,__LINE__,(x)?"ok":"error",#x)
5+
26 enum{ in = 0};
3−#define myassert(X) do{ if(!X) printf("%d: assertion failed\n", __LINE__); }while(0)
4−int main(){
7+
8+int main_1(){
59 {
610 myassert(!in);
711 if(sizeof(enum{in=1})) myassert(in);
@@ -38,6 +42,45 @@ int main(){ · 30 unmodified lines
3842 for(;sizeof(enum{in=1});){ myassert(in); break; }
3943 myassert(!in); //OK
4044 }
45+ return 0;
46+}
47+
48+/* --------------------------------------------- */
49+int main_2()
50+{
51+ char c = 'a';
52+ void func1(char c); /* param 'c' must not shadow local 'c' */
53+ func1(c);
54+ return 0;
55+}
4156
57+void func1(char c)
58+{
59+ myassert(c == 'a');
4260 }
4361
62+struct st { int a; };
63+
64+/* --------------------------------------------- */
65+int main_3()
66+{
67+ struct st func(void);
68+ struct st st = func(); /* not an 'incompatible redefinition' */
69+ myassert(st.a == 10);
70+ return 0;
71+}
72+
73+struct st func(void)
74+{
75+ struct st st = { 10 };
76+ return st;
77+}
78+
79+/* --------------------------------------------- */
80+int main()
81+{
82+ main_1();
83+ main_2();
84+ main_3();
85+ return 0;
86+}
tests/tests2/129_scopes.expect+23−0
@@ -0,0 +1,23 @@
1+129_scopes.c:10: ok : "!in"
2+129_scopes.c:11: ok : "in"
3+129_scopes.c:12: ok : "!in"
4+129_scopes.c:15: ok : "!in"
5+129_scopes.c:16: ok : "in"
6+129_scopes.c:17: ok : "!in"
7+129_scopes.c:20: ok : "!in"
8+129_scopes.c:21: ok : "in"
9+129_scopes.c:22: ok : "!in"
10+129_scopes.c:25: ok : "!in"
11+129_scopes.c:26: ok : "!in"
12+129_scopes.c:27: ok : "!in"
13+129_scopes.c:31: ok : "!in"
14+129_scopes.c:32: ok : "in"
15+129_scopes.c:33: ok : "!in"
16+129_scopes.c:36: ok : "!in"
17+129_scopes.c:37: ok : "in"
18+129_scopes.c:38: ok : "!in"
19+129_scopes.c:41: ok : "!in"
20+129_scopes.c:42: ok : "in"
21+129_scopes.c:43: ok : "!in"
22+129_scopes.c:59: ok : "c == 'a'"
23+129_scopes.c:69: ok : "st.a == 10"

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