diff --git a/Makefile b/Makefile index 9179b982..0a6bcc00 100644 --- a/Makefile +++ b/Makefile @@ -155,8 +155,8 @@ cross: $(LIBTCC1_CROSS) $(PROGS_CROSS) # build specific cross compiler & lib cross-%: %-tcc$(EXESUF) %-libtcc1.a ; -install: all ; @$(MAKE) --no-print-directory install$(CFG) -install-strip: all ; @$(MAKE) --no-print-directory install$(CFG) CONFIG_strip=yes +install: ; @$(MAKE) --no-print-directory install$(CFG) +install-strip: ; @$(MAKE) --no-print-directory install$(CFG) CONFIG_strip=yes uninstall: ; @$(MAKE) --no-print-directory uninstall$(CFG) ifdef CONFIG_cross @@ -190,10 +190,11 @@ endif -include config-extra.mak ifneq ($(X),) +ifneq ($(T),$(NATIVE_TARGET)) # assume support files for cross-targets in "/usr/" by default -TRIPLET-i386 ?= i386-linux-gnu +TRIPLET-i386 ?= i686-linux-gnu TRIPLET-x86_64 ?= x86_64-linux-gnu -TRIPLET-arm ?= arm-linux-gnueabihf +TRIPLET-arm ?= arm-linux-gnueabi TRIPLET-arm64 ?= aarch64-linux-gnu TRIPLET-riscv64 ?= riscv64-linux-gnu TR = $(if $(TRIPLET-$T),$T,ignored) @@ -201,6 +202,7 @@ CRT-$(TR) ?= /usr/$(TRIPLET-$T)/lib LIB-$(TR) ?= {B}:/usr/$(TRIPLET-$T)/lib INC-$(TR) ?= {B}/include:/usr/$(TRIPLET-$T)/include endif +endif CORE_FILES = tcc.c tcctools.c libtcc.c tccpp.c tccgen.c tccdbg.c tccelf.c tccasm.c tccrun.c CORE_FILES += tcc.h config.h libtcc.h tcctok.h @@ -364,12 +366,14 @@ IBw = $(call IB,$(wildcard $1),$2) IF = $(if $1,$(IM) mkdir -p $2 && $(INSTALL) $1 $2) IFw = $(call IF,$(wildcard $1),$2) IR = $(IM) mkdir -p $2 && cp -r $1/. $2 -IM = $(info -> $2 : $1)@ +IM = @echo "-> $2 : $1" ; +BINCHECK = $(if $(wildcard $(PROGS) *-tcc$(EXESUF)),,@echo "Makefile: nothing found to install" && exit 1) B_O = bcheck.o bt-exe.o bt-log.o bt-dll.o # install progs & libs install-unx: + $(call BINCHECK) $(call IBw,$(PROGS) *-tcc,"$(bindir)") $(call IFw,$(LIBTCC1) $(B_O) $(LIBTCC1_U),"$(tccdir)") $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include") @@ -394,14 +398,15 @@ uninstall-unx: # install progs & libs on windows install-win: - $(call IBw,$(PROGS) $(PROGS_CROSS) $(subst libtcc.a,,$(LIBTCC)),"$(bindir)") + $(call BINCHECK) + $(call IBw,$(PROGS) *-tcc.exe libtcc.dll,"$(bindir)") $(call IF,$(TOPSRC)/win32/lib/*.def,"$(tccdir)/lib") $(call IFw,libtcc1.a $(B_O) $(LIBTCC1_W),"$(tccdir)/lib") $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include") $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/include") $(call IR,$(TOPSRC)/win32/examples,"$(tccdir)/examples") $(call IF,$(TOPSRC)/tests/libtcc_test.c,"$(tccdir)/examples") - $(call IFw,$(TOPSRC)/libtcc.h $(subst .dll,.def,$(LIBTCC)),"$(libdir)") + $(call IFw,$(TOPSRC)/libtcc.h libtcc.def,"$(libdir)") $(call IFw,$(TOPSRC)/win32/tcc-win32.txt tcc-doc.html,"$(docdir)") ifneq "$(wildcard $(LIBTCC1_U))" "" $(call IFw,$(LIBTCC1_U),"$(tccdir)/lib") @@ -500,14 +505,15 @@ help: @echo " This file may contain some custom configuration. For example:" @echo " NATIVE_DEFINES += -D..." @echo " Or for example to configure the search paths for a cross-compiler" - @echo " that expects the linux files in /i386-linux:" - @echo " ROOT-i386 = {B}/i386-linux" - @echo " CRT-i386 = {B}/i386-linux/usr/lib" - @echo " LIB-i386 = {B}/i386-linux/lib:{B}/i386-linux/usr/lib" - @echo " INC-i386 = {B}/lib/include:{B}/i386-linux/usr/include" + @echo " assuming the support files in /usr/i686-linux-gnu:" + @echo " ROOT-i386 = /usr/i686-linux-gnu" + @echo " CRT-i386 = {R}/lib" + @echo " LIB-i386 = {B}:{R}/lib" + @echo " INC-i386 = {B}/include:{R}/include (*)" @echo " DEF-i386 += -D__linux__" - @echo " Or to configure a cross compiler for system-files in /usr/" - @echo " TRIPLET-arm-eabi = arm-linux-gnueabi" + @echo " Or also, for the cross platform files in /usr/" + @echo " TRIPLET-i386 = i686-linux-gnu" + @echo " (*) tcc replaces {B} by 'tccdir' and {R} by 'CONFIG_SYSROOT'" # -------------------------------------------------------------------------- endif # ($(INCLUDED),no) diff --git a/include/tccdefs.h b/include/tccdefs.h index 814edf37..c7e1ec01 100644 --- a/include/tccdefs.h +++ b/include/tccdefs.h @@ -309,12 +309,10 @@ #undef __MAYBE_REDIR #undef __RENAME -#if !defined _WIN32 #define __BUILTIN_EXTERN(name,u) \ int __builtin_##name(u int); \ int __builtin_##name##l(u long); \ int __builtin_##name##ll(u long long); - __BUILTIN_EXTERN(ffs,) __BUILTIN_EXTERN(clz, unsigned) __BUILTIN_EXTERN(ctz, unsigned) @@ -322,6 +320,5 @@ __BUILTIN_EXTERN(popcount, unsigned) __BUILTIN_EXTERN(parity, unsigned) #undef __BUILTIN_EXTERN -#endif #endif /* ndef __TCC_PP__ */ diff --git a/tcc.h b/tcc.h index 6f94e2d8..8fb682b7 100644 --- a/tcc.h +++ b/tcc.h @@ -65,12 +65,8 @@ extern long double strtold (const char *__nptr, char **__endptr); # ifndef __GNUC__ # define strtold (long double)strtod # define strtof (float)strtod -# ifndef strtoll -# define strtoll _strtoi64 -# endif -# ifndef strtoull -# define strtoull _strtoui64 -# endif +# define strtoll _strtoi64 +# define strtoull _strtoui64 # endif # ifdef LIBTCC_AS_DLL # define LIBTCCAPI __declspec(dllexport) @@ -1372,9 +1368,6 @@ ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg); ST_FUNC void define_undef(Sym *s); ST_INLN Sym *define_find(int v); ST_FUNC void free_defines(Sym *b); -ST_FUNC Sym *label_find(int v); -ST_FUNC Sym *label_push(Sym **ptop, int v, int flags); -ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep); ST_FUNC void parse_define(void); ST_FUNC void preprocess(int is_bof); ST_FUNC void next(void); @@ -1452,6 +1445,9 @@ ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep); ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c); ST_FUNC Sym *sym_find2(Sym *s, int v); ST_INLN Sym *sym_find(int v); +ST_FUNC Sym *label_find(int v); +ST_FUNC Sym *label_push(Sym **ptop, int v, int flags); +ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep); ST_INLN Sym *struct_find(int v); ST_FUNC Sym *global_identifier_push(int v, int t, int c); diff --git a/tccgen.c b/tccgen.c index da5c81b1..2b4d4ca2 100644 --- a/tccgen.c +++ b/tccgen.c @@ -751,6 +751,63 @@ ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep) *ptop = b; } +/* label lookup */ +ST_FUNC Sym *label_find(int v) +{ + v -= TOK_IDENT; + if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) + return NULL; + return table_ident[v]->sym_label; +} + +ST_FUNC Sym *label_push(Sym **ptop, int v, int flags) +{ + Sym *s, **ps; + s = sym_push2(ptop, v, VT_STATIC, 0); + s->r = flags; + ps = &table_ident[v - TOK_IDENT]->sym_label; + if (ptop == &global_label_stack) { + /* modify the top most local identifier, so that + sym_identifier will point to 's' when popped */ + while (*ps != NULL) + ps = &(*ps)->prev_tok; + } + s->prev_tok = *ps; + *ps = s; + return s; +} + +/* pop labels until element last is reached. Look if any labels are + undefined. Define symbols if '&&label' was used. */ +ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep) +{ + Sym *s, *s1; + for(s = *ptop; s != slast; s = s1) { + s1 = s->prev; + if (s->r == LABEL_DECLARED) { + tcc_warning_c(warn_all)("label '%s' declared but not used", get_tok_str(s->v, NULL)); + } else if (s->r == LABEL_FORWARD) { + tcc_error("label '%s' used but not defined", + get_tok_str(s->v, NULL)); + } else { + if (s->c) { + /* define corresponding symbol. A size of + 1 is put. */ + put_extern_sym(s, cur_text_section, s->jnext, 1); + } + } + /* remove label */ + if (s->r != LABEL_GONE) + table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok; + if (!keep) + sym_free(s); + else + s->r = LABEL_GONE; + } + if (!keep) + *ptop = slast; +} + /* ------------------------------------------------------------------------- */ static void vcheck_cmp(void) { @@ -6762,9 +6819,6 @@ static void new_scope(struct scope *o) o->lstk = local_stack; o->llstk = local_label_stack; ++local_scope; - - if (debug_modes) - tcc_debug_stabn(tcc_state, N_LBRAC, ind - func_ind); } static void prev_scope(struct scope *o, int is_expr) @@ -6789,9 +6843,6 @@ static void prev_scope(struct scope *o, int is_expr) pop_local_syms(o->lstk, is_expr); cur_scope = o->prev; --local_scope; - - if (debug_modes) - tcc_debug_stabn(tcc_state, N_RBRAC, ind - func_ind); } /* leave a scope via break/continue(/goto) */ @@ -6803,6 +6854,20 @@ static void leave_scope(struct scope *o) vla_leave(o); } +/* short versiona for scopes with 'if/do/while/switch' which can + declare only types (of struct/union/enum) */ +static void new_scope_s(struct scope *o) +{ + o->lstk = local_stack; + ++local_scope; +} + +static void prev_scope_s(struct scope *o) +{ + sym_pop(&local_stack, o->lstk, 0); + --local_scope; +} + /* ------------------------------------------------------------------------- */ /* call block from 'for do while' loops */ @@ -6847,7 +6912,7 @@ again: tcc_tcov_check_line (tcc_state, 0), tcc_tcov_block_begin (tcc_state); if (t == TOK_IF) { - //new_scope(&o); //?? breaks tests2.122 + new_scope_s(&o); skip('('); gexpr(); skip(')'); @@ -6862,10 +6927,10 @@ again: } else { gsym(a); } - //prev_scope(&o,0); //?? breaks tests2.122 + prev_scope_s(&o); } else if (t == TOK_WHILE) { - new_scope(&o); + new_scope_s(&o); d = gind(); skip('('); gexpr(); @@ -6876,8 +6941,11 @@ again: gjmp_addr(d); gsym_addr(b, d); gsym(a); - prev_scope(&o,0); + prev_scope_s(&o); + } else if (t == '{') { + if (debug_modes) + tcc_debug_stabn(tcc_state, N_LBRAC, ind - func_ind); new_scope(&o); /* handle local labels declarations */ @@ -6902,6 +6970,8 @@ again: } prev_scope(&o, is_expr); + if (debug_modes) + tcc_debug_stabn(tcc_state, N_RBRAC, ind - func_ind); if (local_scope) next(); else if (!nocode_wanted) @@ -6988,7 +7058,7 @@ again: prev_scope(&o, 0); } else if (t == TOK_DO) { - new_scope(&o); + new_scope_s(&o); a = b = 0; d = gind(); lblock(&a, &b); @@ -6998,15 +7068,14 @@ again: gexpr(); skip(')'); skip(';'); - prev_scope(&o,0); c = gvtst(0, 0); gsym_addr(c, d); gsym(a); + prev_scope_s(&o); } else if (t == TOK_SWITCH) { struct switch_t *sw; - new_scope(&o); sw = tcc_mallocz(sizeof *sw); sw->bsym = &a; sw->scope = cur_scope; @@ -7014,17 +7083,18 @@ again: sw->nocode_wanted = nocode_wanted; cur_switch = sw; + new_scope_s(&o); skip('('); gexpr(); skip(')'); sw->sv = *vtop--; /* save switch value */ - a = 0; b = gjmp(0); /* jump to first case */ lblock(&a, NULL); a = gjmp(a); /* add implicit break */ /* case lookup */ gsym(b); + prev_scope_s(&o); if (sw->nocode_wanted) goto skip_switch; @@ -7052,7 +7122,6 @@ again: dynarray_reset(&sw->p, &sw->n); cur_switch = sw->prev; tcc_free(sw); - prev_scope(&o,0); } else if (t == TOK_CASE) { struct case_t *cr = tcc_malloc(sizeof(struct case_t)); @@ -7085,8 +7154,7 @@ again: goto block_after_label; } else if (t == TOK_GOTO) { - if (cur_scope->vla.num) - vla_restore(cur_scope->vla.locorig); + vla_restore(cur_scope->vla.locorig); if (tok == '*' && gnu_ext) { /* computed goto */ next(); diff --git a/tccpp.c b/tccpp.c index 6322e8b8..64de770f 100644 --- a/tccpp.c +++ b/tccpp.c @@ -577,17 +577,13 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv) break; case TOK_CFLOAT: - cstr_cat(&cstr_buf, "", 0); - break; + return strcpy(p, ""); case TOK_CDOUBLE: - cstr_cat(&cstr_buf, "", 0); - break; + return strcpy(p, ""); case TOK_CLDOUBLE: - cstr_cat(&cstr_buf, "", 0); - break; + return strcpy(p, ""); case TOK_LINENUM: - cstr_cat(&cstr_buf, "", 0); - break; + return strcpy(p, ">="); case TOK_EOF: return strcpy(p, ""); + case 0: /* anonymous nameless symbols */ + return strcpy(p, ""); default: if (v < TOK_IDENT) { /* search in two bytes table */ @@ -617,13 +615,12 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv) } q += 3; } - if (v >= 127) { - sprintf(cstr_buf.data, "<%02x>", v); - return cstr_buf.data; - } - addv: + if (v >= 127 || (v < 32 && !is_space(v) && v != '\n')) { + sprintf(p, "<\\x%02x>", v); + break; + } + addv: *p++ = v; - case 0: /* nameless anonymous symbol */ *p = '\0'; } else if (v < tok_ident) { return table_ident[v - TOK_IDENT]->str; @@ -1327,63 +1324,6 @@ ST_FUNC void free_defines(Sym *b) } } -/* label lookup */ -ST_FUNC Sym *label_find(int v) -{ - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) - return NULL; - return table_ident[v]->sym_label; -} - -ST_FUNC Sym *label_push(Sym **ptop, int v, int flags) -{ - Sym *s, **ps; - s = sym_push2(ptop, v, VT_STATIC, 0); - s->r = flags; - ps = &table_ident[v - TOK_IDENT]->sym_label; - if (ptop == &global_label_stack) { - /* modify the top most local identifier, so that - sym_identifier will point to 's' when popped */ - while (*ps != NULL) - ps = &(*ps)->prev_tok; - } - s->prev_tok = *ps; - *ps = s; - return s; -} - -/* pop labels until element last is reached. Look if any labels are - undefined. Define symbols if '&&label' was used. */ -ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep) -{ - Sym *s, *s1; - for(s = *ptop; s != slast; s = s1) { - s1 = s->prev; - if (s->r == LABEL_DECLARED) { - tcc_warning_c(warn_all)("label '%s' declared but not used", get_tok_str(s->v, NULL)); - } else if (s->r == LABEL_FORWARD) { - tcc_error("label '%s' used but not defined", - get_tok_str(s->v, NULL)); - } else { - if (s->c) { - /* define corresponding symbol. A size of - 1 is put. */ - put_extern_sym(s, cur_text_section, s->jnext, 1); - } - } - /* remove label */ - if (s->r != LABEL_GONE) - table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok; - if (!keep) - sym_free(s); - else - s->r = LABEL_GONE; - } - if (!keep) - *ptop = slast; -} - /* fake the nth "#if defined test_..." for tcc -dt -run */ static void maybe_run_test(TCCState *s) { diff --git a/tests/tcctest.c b/tests/tcctest.c index 5db044d8..6ae5a773 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -2889,7 +2889,8 @@ void relocation_test(void) printf("*rel2=%d\n", *rel2); fptr(); #ifdef __LP64__ - printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63); + // compare 'addend' displacement versus conventional arithmetics + printf("pa_symbol: %d\n", (long)&rel1 == __pa_symbol() - 0x80000000); #endif } @@ -3857,10 +3858,11 @@ int constant_p_var; int func(void); -#if !defined _WIN32 + /* __builtin_clz and __builtin_ctz return random values for 0 */ static void builtin_test_bits(unsigned long long x, int cnt[]) { +#if GCC_MAJOR >= 4 cnt[0] += __builtin_ffs(x); cnt[1] += __builtin_ffsl(x); cnt[2] += __builtin_ffsll(x); @@ -3884,8 +3886,8 @@ static void builtin_test_bits(unsigned long long x, int cnt[]) cnt[15] += __builtin_parity(x); cnt[16] += __builtin_parityl(x); cnt[17] += __builtin_parityll(x); -} #endif +} void builtin_test(void) { @@ -3941,7 +3943,6 @@ void builtin_test(void) //printf("bera: %p\n", __builtin_extract_return_addr((void*)43)); -#if !defined _WIN32 { int cnt[18]; unsigned long long r = 0; @@ -3958,7 +3959,6 @@ void builtin_test(void) for (i = 0; i < 18; i++) printf ("%d %d\n", i, cnt[i]); } -#endif } #if defined _WIN32 diff --git a/tests/tests2/119_random_stuff.c b/tests/tests2/119_random_stuff.c index 42b6a178..0b7a4e50 100644 --- a/tests/tests2/119_random_stuff.c +++ b/tests/tests2/119_random_stuff.c @@ -1,15 +1,4 @@ -#if defined(_WIN32) -/* - * strtoll and strtoull require the following define. - * Not really needed in our case - */ - #if !defined(_ISOC99_SOURCE) - #define _ISOC99_SOURCE 1 - #endif -#endif - #include -#include struct big_struct { char a[262144]; }; @@ -99,33 +88,6 @@ void tst_cast(void) printf ("schar to ushort cast: %x\n", r); } -void tst_strtoll_strtoull(void) -{ - /* - * It probably makes sense to run this test on all systems, - * not just on Windows. - */ -#if defined(_WIN32) - const unsigned int shift = 32; - - { - long long x = strtoll("0x100000000", NULL, 0); - x = (x >> shift); - if (x != 1LL) { - printf("Windows: strtoll error\n"); - } - } - - { - unsigned long long x = strtoull("0x100000000", NULL, 0); - x = (x >> shift); - if (x != 1) { - printf ("Windows: strtoull error\n"); - } - } -#endif -} - struct { int (*print)(const char *format, ...); } tst_indir = { @@ -154,6 +116,5 @@ main (void) tst_compare(); tst_pack(); tst_cast(); - tst_strtoll_strtoull(); tst_indir_func(); } diff --git a/tests/tests2/122_vla_reuse.c b/tests/tests2/122_vla_reuse.c index d894af87..feb47de5 100644 --- a/tests/tests2/122_vla_reuse.c +++ b/tests/tests2/122_vla_reuse.c @@ -12,7 +12,7 @@ main (void) int x[n % 100 + 1]; if (first == 0) { if (&x[0] != p[n % 100 + 1]) { - printf ("ERROR: %d %p $p\n", &x[0], p[n % 100 + 1]); + printf ("ERROR: %p %p\n", &x[0], p[n % 100 + 1]); return(1); } } diff --git a/tests/tests2/129_scopes.c b/tests/tests2/129_scopes.c index 092abb12..b63b6822 100644 --- a/tests/tests2/129_scopes.c +++ b/tests/tests2/129_scopes.c @@ -2,13 +2,11 @@ enum{ in = 0}; #define myassert(X) do{ if(!X) printf("%d: assertion failed\n", __LINE__); }while(0) int main(){ - #if 0 { myassert(!in); if(sizeof(enum{in=1})) myassert(in); myassert(!in); //OOPS } - #endif { myassert(!in); switch(sizeof(enum{in=1})) { default: myassert(in); } diff --git a/win32/include/stdlib.h b/win32/include/stdlib.h index 36e8b60d..a0ca376f 100644 --- a/win32/include/stdlib.h +++ b/win32/include/stdlib.h @@ -536,7 +536,7 @@ extern "C" { #endif #endif -#if !defined __NO_ISOCEXT +#if !defined __NO_ISOCEXT /* externs in static libmingwex.a */ typedef struct { long long quot, rem; } lldiv_t; @@ -544,18 +544,13 @@ extern "C" { __CRT_INLINE long long __cdecl llabs(long long _j) { return (_j >= 0 ? _j : -_j); } - /* stro[u]ll do not properly map in Windows; use macros as VC++ does */ - #if !defined(strtoll) + #ifdef __TINYC__ /* gr */ #define strtoll _strtoi64 - #endif - #if !defined(strtoull) #define strtoull _strtoui64 - #endif - -/* + #else long long __cdecl strtoll(const char* __restrict__, char** __restrict, int); unsigned long long __cdecl strtoull(const char* __restrict__, char** __restrict__, int); -*/ + #endif /* these are stubs for MS _i64 versions */ long long __cdecl atoll (const char *);