small scopes cleanup etc.

tccgen.c:
- just track local_stack for small scopes (can't declare variables)
- fix a vla problem with nested scopes
- move debug N_L/RBRAC into curly braced block

Also:
- tccpp.c: move 'label_...' functions to tccgen.c
- tccpp.c: let get_tok_str() say "<no name>" for anonymous symbols
- tcctest.c: let __pa_symbol() work for memory > 2GB
- 119_random_stuff.c: revert strtoll test (no reason to test libc)
- tccdefs.h/tcctest.c: enable bit fncs for _WIN32
- Makefile:
  - use i686-linux-gnu instead of i386-linux-gnu for cross-i386
  - update 'make help'
  - revert umplicit 'make all' with 'make install' (but print warning)
This commit is contained in:
grischka 2023-03-06 02:04:17 +01:00
parent 5f08561e10
commit 19e3e10e4b
10 changed files with 131 additions and 170 deletions

View File

@ -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/<triplet>" 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 <tccdir>/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/<triplet>"
@echo " TRIPLET-arm-eabi = arm-linux-gnueabi"
@echo " Or also, for the cross platform files in /usr/<triplet>"
@echo " TRIPLET-i386 = i686-linux-gnu"
@echo " (*) tcc replaces {B} by 'tccdir' and {R} by 'CONFIG_SYSROOT'"
# --------------------------------------------------------------------------
endif # ($(INCLUDED),no)

View File

@ -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__ */

14
tcc.h
View File

@ -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);

102
tccgen.c
View File

@ -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();

82
tccpp.c
View File

@ -577,17 +577,13 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv)
break;
case TOK_CFLOAT:
cstr_cat(&cstr_buf, "<float>", 0);
break;
return strcpy(p, "<float>");
case TOK_CDOUBLE:
cstr_cat(&cstr_buf, "<double>", 0);
break;
return strcpy(p, "<double>");
case TOK_CLDOUBLE:
cstr_cat(&cstr_buf, "<long double>", 0);
break;
return strcpy(p, "<long double>");
case TOK_LINENUM:
cstr_cat(&cstr_buf, "<linenumber>", 0);
break;
return strcpy(p, "<linenumber");
/* above tokens have value, the ones below don't */
case TOK_LT:
@ -604,6 +600,8 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv)
return strcpy(p, ">>=");
case TOK_EOF:
return strcpy(p, "<eof>");
case 0: /* anonymous nameless symbols */
return strcpy(p, "<no name>");
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)
{

View File

@ -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

View File

@ -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 <stdio.h>
#include <stdlib.h>
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();
}

View File

@ -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);
}
}

View File

@ -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); }

View File

@ -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 *);