Skip to content

Commit 7e01b20

Browse files
author
grischka
committed
tccgen: void values, etc...
originally, this was meant to avoid 'void' values leak to the gen-xxx.c generators which would otherwise try to load void from/to registers. Also catch invalid types such as 'unsigned bool' eariler. tccgen.c: - expr_cond()/gexpr(): ignore VT_VOID - gen_cast(): set float reg with static initializers to make backends happier with invalid input - init_putv(): improve static compound literal initializers Also: - ignore "missing prototype" and "might return no value" for old style K&R functions tcc.c, libtcc.c: - tcc_set_output_type(): return errors from loading crt1.o tcc.h/tccpp.c: - fix horrible longstanding mistake with sizeof SValue.tab. Must have place for sizeof (long double) rather than the target's LDOUBLE_SIZE. tccdefs.h: - add a fake __[u]int128_t for all platforms arm-gen.c: - gen_cvt_ftof() must load to reg always arm64-gen.c: - simplify arm64_pcs() a bit i386/x86_64-gen.c: - do not assume char is signed (for cross compilation arm->x86) tccelf/macho linker message: - instead of "undefined symbol 'X'" now say "unresolved reference to 'X'" which makes it more clear that it is a _linker_error_. tccasm.c: - .align/p2align: use 'nop's in exec sections
1 parent 016087c commit 7e01b20

15 files changed

Lines changed: 161 additions & 151 deletions

File tree

arm-gen.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2283,8 +2283,9 @@ void gen_cvt_ftoi(int t)
22832283
void gen_cvt_ftof(int t)
22842284
{
22852285
#ifdef TCC_ARM_VFP
2286+
uint32_t r = gv(RC_FLOAT);
22862287
if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
2287-
uint32_t r = vfpr(gv(RC_FLOAT));
2288+
r = vfpr(r);
22882289
o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t));
22892290
}
22902291
#else

arm64-gen.c

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,6 @@ static int arm64_type_size(int t)
278278
case VT_DOUBLE: return 3;
279279
case VT_LDOUBLE: return 4;
280280
case VT_BOOL: return 0;
281-
case VT_VOID: return 0;
282281
}
283282
assert(0);
284283
return 0;
@@ -832,11 +831,10 @@ static unsigned long arm64_pcs_aux(int variadic, int n, CType **type, unsigned l
832831

833832
for (i = 0; i < n; i++) {
834833
int hfa = arm64_hfa(type[i], 0);
835-
int win_vararg_float = 0;
836-
int size, align;
834+
int size, align, bt;
837835

838-
if ((type[i]->t & VT_ARRAY) ||
839-
(type[i]->t & VT_BTYPE) == VT_FUNC)
836+
bt = type[i]->t & VT_BTYPE;
837+
if (bt == VT_PTR || bt == VT_FUNC)
840838
size = align = 8;
841839
else
842840
size = type_size(type[i], &align);
@@ -848,13 +846,10 @@ static unsigned long arm64_pcs_aux(int variadic, int n, CType **type, unsigned l
848846
}
849847

850848
#elif defined(TCC_TARGET_PE)
851-
if (variadic && i >= variadic && (hfa || is_float(type[i]->t))) {
849+
if (variadic && i >= variadic) {
852850
hfa = 0;
853-
if (is_float(type[i]->t)) {
854-
win_vararg_float = 1;
855-
size = 8;
856-
align = 8;
857-
}
851+
if (is_float(bt))
852+
bt = VT_INT, size = align = 8;
858853
}
859854
#endif
860855
if (hfa)
@@ -871,12 +866,12 @@ static unsigned long arm64_pcs_aux(int variadic, int n, CType **type, unsigned l
871866
}
872867
continue;
873868
}
874-
else if ((type[i]->t & VT_BTYPE) == VT_STRUCT)
869+
else if (bt == VT_STRUCT)
875870
// B.4
876871
size = (size + 7) & ~7;
877872

878873
// C.1
879-
if (!win_vararg_float && is_float(type[i]->t) && nv < 8) {
874+
if (is_float(bt) && nv < 8) {
880875
a[i] = 16 + (nv++ << 1);
881876
continue;
882877
}
@@ -895,24 +890,24 @@ static unsigned long arm64_pcs_aux(int variadic, int n, CType **type, unsigned l
895890
}
896891

897892
// C.4
898-
if (hfa || (type[i]->t & VT_BTYPE) == VT_LDOUBLE) {
893+
if (hfa || bt == VT_LDOUBLE) {
899894
ns = (ns + 7) & ~7;
900895
ns = (ns + align - 1) & -align;
901896
}
902897

903898
// C.5
904-
if ((type[i]->t & VT_BTYPE) == VT_FLOAT)
899+
if (bt == VT_FLOAT)
905900
size = 8;
906901

907902
// C.6
908-
if (!win_vararg_float && (hfa || is_float(type[i]->t))) {
903+
if (hfa || is_float(bt)) {
909904
a[i] = ns;
910905
ns += size;
911906
continue;
912907
}
913908

914909
// C.7
915-
if ((type[i]->t & VT_BTYPE) != VT_STRUCT && size <= 8 && nx < 8) {
910+
if (bt != VT_STRUCT && size <= 8 && nx < 8) {
916911
a[i] = nx++ << 1;
917912
continue;
918913
}
@@ -922,14 +917,14 @@ static unsigned long arm64_pcs_aux(int variadic, int n, CType **type, unsigned l
922917
nx = (nx + 1) & ~1;
923918

924919
// C.9
925-
if ((type[i]->t & VT_BTYPE) != VT_STRUCT && size == 16 && nx < 7) {
920+
if (bt != VT_STRUCT && size == 16 && nx < 7) {
926921
a[i] = nx << 1;
927922
nx += 2;
928923
continue;
929924
}
930925

931926
// C.10
932-
if ((type[i]->t & VT_BTYPE) == VT_STRUCT && size <= (8 - nx) * 8) {
927+
if (bt == VT_STRUCT && size <= (8 - nx) * 8) {
933928
a[i] = nx << 1;
934929
nx += (size + 7) >> 3;
935930
continue;
@@ -943,7 +938,7 @@ static unsigned long arm64_pcs_aux(int variadic, int n, CType **type, unsigned l
943938
ns = (ns + align - 1) & -align;
944939

945940
// C.13
946-
if ((type[i]->t & VT_BTYPE) == VT_STRUCT) {
941+
if (bt == VT_STRUCT) {
947942
a[i] = ns;
948943
ns += size;
949944
continue;
@@ -974,11 +969,11 @@ static unsigned long arm64_pcs(int variadic, int n, CType **type, unsigned long
974969
}
975970

976971
// Argument types:
977-
stack = arm64_pcs_aux(variadic, n, type + 1, a + 1);
972+
stack = arm64_pcs_aux(variadic, n - 1, type + 1, a + 1);
978973

979974
if (0) {
980975
int i;
981-
for (i = 0; i <= n; i++) {
976+
for (i = 0; i < n; i++) {
982977
if (!i)
983978
printf("arm64_pcs return: ");
984979
else
@@ -1076,9 +1071,9 @@ ST_FUNC void gfunc_call(int nb_args)
10761071

10771072
stack = arm64_pcs(
10781073
#ifdef TCC_TARGET_PE
1079-
old_style ? -1 :
1074+
old_style ? /* all args like varargs in K&R style */ -1 :
10801075
#endif
1081-
var_nb_arg, nb_args, t, a);
1076+
var_nb_arg, nb_args + 1, t, a);
10821077

10831078
// Allocate space for structs replaced by pointer:
10841079
for (i = nb_args; i; i--)
@@ -1258,43 +1253,39 @@ ST_FUNC void gfunc_prolog(Sym *func_sym)
12581253
CType *func_type = &func_sym->type;
12591254
int n = 0;
12601255
int i = 0;
1261-
int pcs_n;
12621256
Sym *sym;
12631257
CType **t;
12641258
unsigned long *a;
12651259
int use_x8 = 0;
12661260
int last_int = 0;
12671261
int last_float = 0;
12681262
int variadic = func_sym->type.ref->f.func_type == FUNC_ELLIPSIS;
1269-
int var_nb_arg = n_func_args(&func_sym->type);
1270-
int c;
1263+
int var_nb_arg = variadic ? n_func_args(&func_sym->type) : 0;
12711264

12721265
func_vc = 144; // offset of where x8 is stored
12731266

12741267
for (sym = func_type->ref; sym; sym = sym->next)
12751268
++n;
12761269

1277-
pcs_n = n - 1;
1278-
c = n + variadic;
1279-
t = tcc_malloc(c * sizeof(*t));
1280-
a = tcc_malloc(c * sizeof(*a));
1270+
#ifdef TCC_TARGET_PE
1271+
n += variadic;
1272+
#endif
12811273

1274+
t = tcc_malloc(n * sizeof(*t));
1275+
a = tcc_malloc(n * sizeof(*a));
12821276
for (sym = func_type->ref; sym; sym = sym->next)
12831277
t[i++] = &sym->type;
12841278

12851279
#ifdef TCC_TARGET_PE
1286-
if (variadic) {
1287-
t[i++] = &int_type;
1288-
++pcs_n;
1289-
}
1280+
if (variadic)
1281+
t[i] = &int_type;
12901282
#endif
12911283

1292-
arm64_func_va_list_stack = arm64_pcs(variadic ? var_nb_arg : 0,
1293-
pcs_n, t, a);
1284+
arm64_func_va_list_stack = arm64_pcs(var_nb_arg, n, t, a);
12941285

12951286
#ifdef TCC_TARGET_PE
12961287
if (variadic)
1297-
arm64_func_va_list_stack = arm64_pe_param_off(a[n]);
1288+
arm64_func_va_list_stack = arm64_pe_param_off(a[n - 1]);
12981289
#endif
12991290

13001291
#if !defined(TCC_TARGET_MACHO)
@@ -1304,6 +1295,7 @@ ST_FUNC void gfunc_prolog(Sym *func_sym)
13041295
last_float = 4;
13051296
}
13061297
#endif
1298+
13071299
if (a && a[0] == 1)
13081300
use_x8 = 1;
13091301
for (i = 1, sym = func_type->ref->next; sym; i++, sym = sym->next) {
@@ -1563,7 +1555,8 @@ ST_FUNC void gfunc_return(CType *func_type)
15631555
CType *t = func_type;
15641556
unsigned long a;
15651557

1566-
arm64_pcs(0, 0, &t, &a);
1558+
arm64_pcs(0, 1, &t, &a);
1559+
15671560
switch (a) {
15681561
case -1:
15691562
break;

i386-gen.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ static void gen_modrm(int opc, int op_r2, int r, Sym *sym, int c)
271271
} else if ((r & VT_VALMASK) == VT_LOCAL) {
272272
o(opc);
273273
/* currently, we use only ebp as base */
274-
if (c == (char)c) {
274+
if (c == (signed char)c) {
275275
/* short reference */
276276
o(0x45 | op_reg);
277277
g(c);
@@ -439,7 +439,7 @@ ST_FUNC void store(int r, SValue *v)
439439

440440
static void gadd_sp(int val)
441441
{
442-
if (val == (char)val) {
442+
if (val == (signed char)val) {
443443
o(0xc483);
444444
g(val);
445445
} else {
@@ -774,7 +774,7 @@ ST_FUNC void gjmp_addr(int a)
774774
{
775775
int r;
776776
r = a - ind - 2;
777-
if (r == (char)r) {
777+
if (r == (signed char)r) {
778778
g(0xeb);
779779
g(r);
780780
} else {
@@ -787,7 +787,7 @@ ST_FUNC void gjmp_addr(int a)
787787
ST_FUNC void gjmp_cond_addr(int a, int op)
788788
{
789789
int r = a - ind - 2;
790-
if (r == (char)r)
790+
if (r == (signed char)r)
791791
g(op - 32), g(r);
792792
else
793793
g(0x0f), gjmp2(op - 16, r - 4);
@@ -830,7 +830,7 @@ ST_FUNC void gen_opi(int op)
830830
r = gv(RC_INT);
831831
vswap();
832832
c = vtop->c.i;
833-
if (c == (char)c) {
833+
if (c == (signed char)c) {
834834
/* generate inc and dec for smaller code */
835835
if ((c == 1 || c == -1) && (op == '+' || op == '-')) {
836836
opc = (c == 1) ^ (op == '+');

include/tccdefs.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,6 @@
9090
#define __NO_TLS 1
9191
#define __RUNETYPE_INTERNAL 1
9292
# if __SIZEOF_POINTER__ == 8
93-
/* FIXME, __int128_t is used by setjump */
94-
#define __int128_t struct { unsigned char _dummy[16] __attribute((aligned(16))); }
9593
#define __SIZEOF_SIZE_T__ 8
9694
#define __SIZEOF_PTRDIFF_T__ 8
9795
#else
@@ -142,12 +140,6 @@
142140
#endif
143141
#define __INT32_TYPE__ int
144142

145-
#if defined __aarch64__
146-
/* GCC's __uint128_t appears in some Linux/OSX header files. Make it a
147-
synonym for long double to get the size and alignment right. */
148-
#define __uint128_t long double
149-
#endif
150-
151143
#if !defined _WIN32
152144
/* glibc defines. We do not support __USER_NAME_PREFIX__ */
153145
#define __REDIRECT(name, proto, alias) name proto __asm__ (#alias)
@@ -187,6 +179,12 @@
187179
# endif
188180
#endif
189181

182+
/* GCC's __uint128_t appears in some Linux/OSX header files.
183+
Just make it some type with same size and alignment. */
184+
struct __uint128__ { char x[16]; } __attribute((__aligned__(16)));
185+
#define __int128_t struct __uint128__
186+
#define __uint128_t struct __uint128__
187+
190188
/* __builtin_va_list */
191189
#if defined __x86_64__
192190
#if !defined _WIN32

libtcc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ static void *default_reallocator(void *ptr, unsigned long size)
252252
else {
253253
ptr1 = realloc(ptr, size);
254254
if (!ptr1) {
255-
fprintf(stderr, "memory full\n");
255+
fprintf(stderr, "tcc: memory full\n");
256256
exit (1);
257257
}
258258
}
@@ -1003,9 +1003,9 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
10031003
/* paths for crt objects */
10041004
tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
10051005
if (output_type != TCC_OUTPUT_MEMORY && !s->nostdlib)
1006-
tccelf_add_crtbegin(s);
1006+
tccelf_add_crtbegin(s); /* may produce errors */
10071007
#endif
1008-
return 0;
1008+
return s->nb_errors ? -1 : 0;
10091009
}
10101010

10111011
LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)

tcc.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static const char help[] =
3535
"General options:\n"
3636
" -c compile only - generate an object file\n"
3737
" -o outfile set output filename\n"
38-
" -run run compiled source [with custom stdin: -rstdin FILE]\n"
38+
" -run run compiled source\n"
3939
" -fflag set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n"
4040
" -Wwarning set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"
4141
" -w disable all warnings\n"
@@ -105,6 +105,7 @@ static const char help2[] =
105105
" -static link to static libraries (not recommended)\n"
106106
" -dumpversion print version\n"
107107
" -print-search-dirs print search paths\n"
108+
" -rstdin file with -run: use 'file' as custom stdin\n"
108109
" -dt with -run/-E: auto-define 'test_...' macros\n"
109110
"Ignored options:\n"
110111
" -arch -C --param -pedantic -pipe -s -traditional\n"
@@ -354,9 +355,10 @@ int main(int argc, char **argv)
354355
set_environment(s);
355356
if (s->output_type == 0)
356357
s->output_type = TCC_OUTPUT_EXE;
357-
tcc_set_output_type(s, s->output_type);
358+
ret = tcc_set_output_type(s, s->output_type);
358359
if (ppfp)
359360
s->ppfp = ppfp;
361+
360362
if ((s->output_type == TCC_OUTPUT_MEMORY
361363
|| s->output_type == TCC_OUTPUT_PREPROCESS)
362364
&& (s->dflag & 16)) { /* -dt option */
@@ -369,7 +371,7 @@ int main(int argc, char **argv)
369371

370372
/* compile or add each files or library */
371373
first_file = NULL;
372-
do {
374+
while (0 == ret) {
373375
struct filespec *f = s->files[n];
374376
s->filetype = f->type;
375377
if (f->type & AFF_TYPE_LIB) {
@@ -381,9 +383,11 @@ int main(int argc, char **argv)
381383
first_file = f->name;
382384
ret = tcc_add_file(s, f->name);
383385
}
384-
} while (++n < s->nb_files
385-
&& 0 == ret
386-
&& (s->output_type != TCC_OUTPUT_OBJ || s->option_r));
386+
if (++n == s->nb_files)
387+
break;
388+
if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r)
389+
break;
390+
}
387391

388392
if (s->do_bench)
389393
end_time = getclock_ms();

0 commit comments

Comments
 (0)