History

__builtin_/__bound_: A 'stay tiny' approach to the matter

tccgen.c: - cleanup __builtin_... stuff - merge __attribute((alias("sym"))) with __asm__("sym") Now one cannot have both, however for alias underscores are added if enabled. For __asm__ they aren't. tccpp.c: - extend tcc_predefs accordingly. Was generated with 'cd tests/misc && tcc -run c2str.c tcc_predef.h tcc_predefs' xxx-gen.c: - move bcheck setjmp test to tccgen.c:gbound_args() i386-gen.c: - create win32 compatible stack space for big structures tcctest.c: - some cleanup + nicer output

grischka committed 6 years ago

Commit 2a0167a1 parent 6a4f3cf16 files · +641 −719Browse files

Unified · Split

16 files
  1. arm-gen.c +1 −9
  2. arm64-gen.c +1 −9
  3. i386-asm.c +1 −1
  4. i386-gen.c +11 −13
  5. libtcc.c +7 −8
  6. riscv64-gen.c +1 −9
  7. tcc.h +1 −1
  8. tccgen.c +71 −317
  9. tccpp.c +52 −7
  10. tcctok.h +0 −55
  11. tests/misc/c2str.c +112 −0
  12. tests/misc/tcc_predefs.h +111 −0
  13. tests/tcctest.c +145 −277
  14. tests/tests2/61_integers.c +70 −0
  15. tests/tests2/61_integers.expect +56 −0
  16. x86_64-gen.c +1 −13
arm-gen.c+1−9
@@ -161,7 +161,7 @@ static int leaffunc; · 160 unmodified lines
161161 #if defined(CONFIG_TCC_BCHECK)
162162 static addr_t func_bound_offset;
163163 static unsigned long func_bound_ind;
164−static int func_bound_add_epilog;
164+ST_DATA int func_bound_add_epilog;
165165 #endif
166166
167167 #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
@@ -763,14 +763,6 @@ static void gcall_or_jmp(int is_jmp) · 595 unmodified lines
763763 greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32);
764764 o(vtop->c.i);
765765 }
766−#ifdef CONFIG_TCC_BCHECK
767− if (tcc_state->do_bounds_check &&
768− (vtop->sym->v == TOK_setjmp ||
769− vtop->sym->v == TOK__setjmp ||
770− vtop->sym->v == TOK_sigsetjmp ||
771− vtop->sym->v == TOK___sigsetjmp))
772− func_bound_add_epilog = 1;
773−#endif
774766 }else{
775767 if(!is_jmp)
776768 o(0xE28FE004); // add lr,pc,#4
arm64-gen.c+1−9
@@ -84,7 +84,7 @@ ST_DATA const int reg_classes[NB_REGS] = { · 83 unmodified lines
8484 #if defined(CONFIG_TCC_BCHECK)
8585 static addr_t func_bound_offset;
8686 static unsigned long func_bound_ind;
87−static int func_bound_add_epilog;
87+ST_DATA int func_bound_add_epilog;
8888 #endif
8989
9090 #define IS_FREG(x) ((x) >= TREG_F(0))
@@ -606,14 +606,6 @@ static void arm64_gen_bl_or_b(int b) · 515 unmodified lines
606606 greloca(cur_text_section, vtop->sym, ind,
607607 b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0);
608608 o(0x14000000 | (uint32_t)!b << 31); // b/bl .
609−#ifdef CONFIG_TCC_BCHECK
610− if (tcc_state->do_bounds_check &&
611− (vtop->sym->v == TOK_setjmp ||
612− vtop->sym->v == TOK__setjmp ||
613− vtop->sym->v == TOK_sigsetjmp ||
614− vtop->sym->v == TOK___sigsetjmp))
615− func_bound_add_epilog = 1;
616−#endif
617609 }
618610 else {
619611 #ifdef CONFIG_TCC_BCHECK
i386-asm.c+1−1
@@ -1202,7 +1202,7 @@ ST_FUNC int asm_parse_regvar (int t) · 1201 unmodified lines
12021202 {
12031203 const char *s;
12041204 Operand op;
1205− if (t < TOK_IDENT)
1205+ if (t < TOK_IDENT || (t & SYM_FIELD))
12061206 return -1;
12071207 s = table_ident[t - TOK_IDENT]->str;
12081208 if (s[0] != '%')
i386-gen.c+11−13
@@ -97,7 +97,7 @@ static int func_ret_sub; · 96 unmodified lines
9797 #ifdef CONFIG_TCC_BCHECK
9898 static addr_t func_bound_offset;
9999 static unsigned long func_bound_ind;
100−static int func_bound_add_epilog;
100+ST_DATA int func_bound_add_epilog;
101101 static void gen_bounds_prolog(void);
102102 static void gen_bounds_epilog(void);
103103 #endif
@@ -359,18 +359,6 @@ static void gcall_or_jmp(int is_jmp) · 255 unmodified lines
359359 /* constant and relocation case */
360360 greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32);
361361 oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
362−#ifdef CONFIG_TCC_BCHECK
363− if (tcc_state->do_bounds_check &&
364− (vtop->sym->v == TOK_alloca ||
365− vtop->sym->v == TOK_setjmp ||
366− vtop->sym->v == TOK__setjmp
367−#ifndef TCC_TARGET_PE
368− || vtop->sym->v == TOK_sigsetjmp
369− || vtop->sym->v == TOK___sigsetjmp
370−#endif
371− ))
372− func_bound_add_epilog = 1;
373−#endif
374362 } else {
375363 /* otherwise, indirect call */
376364 r = gv(RC_INT);
@@ -429,6 +417,16 @@ ST_FUNC void gfunc_call(int nb_args) · 52 unmodified lines
429417 /* align to stack align size */
430418 size = (size + 3) & ~3;
431419 /* allocate the necessary size on stack */
420+#ifdef TCC_TARGET_PE
421+ if (size >= 0x4096) {
422+ o(0x5250);
423+ oad(0x68, size);
424+ vpush_global_sym(&func_old_type, TOK_alloca);
425+ gcall_or_jmp(0);
426+ vtop--;
427+ o(0x58585a);
428+ } else
429+#endif
432430 oad(0xec81, size); /* sub $xxx, %esp */
433431 /* generate structure store */
434432 r = get_reg(RC_INT);
libtcc.c+7−8
@@ -967,14 +967,13 @@ LIBTCCAPI TCCState *tcc_new(void) · 966 unmodified lines
967967 tcc_define_symbol(s, "_FORTIFY_SOURCE", "0");
968968 #endif /* ndef TCC_TARGET_MACHO */
969969
970− if (PTR_SIZE == 4) {
971− tcc_define_symbol(s, "__SIZEOF_LONG__", "4");
972− tcc_define_symbol(s, "__LONG_MAX__", "0x7fffffffL");
973− }
974− else {
975− tcc_define_symbol(s, "__SIZEOF_LONG__", "8");
976− tcc_define_symbol(s, "__LONG_MAX__", "0x7fffffffffffffffL");
977− }
970+#if LONG_SIZE == 4
971+ tcc_define_symbol(s, "__SIZEOF_LONG__", "4");
972+ tcc_define_symbol(s, "__LONG_MAX__", "0x7fffffffL");
973+#else
974+ tcc_define_symbol(s, "__SIZEOF_LONG__", "8");
975+ tcc_define_symbol(s, "__LONG_MAX__", "0x7fffffffffffffffL");
976+#endif
978977 tcc_define_symbol(s, "__SIZEOF_INT__", "4");
979978 tcc_define_symbol(s, "__SIZEOF_LONG_LONG__", "8");
980979 tcc_define_symbol(s, "__CHAR_BIT__", "8");
riscv64-gen.c+1−9
@@ -66,7 +66,7 @@ ST_DATA const int reg_classes[NB_REGS] = { · 65 unmodified lines
6666 #if defined(CONFIG_TCC_BCHECK)
6767 static addr_t func_bound_offset;
6868 static unsigned long func_bound_ind;
69−static int func_bound_add_epilog;
69+ST_DATA int func_bound_add_epilog;
7070 #endif
7171
7272 static int ireg(int r)
@@ -387,14 +387,6 @@ static void gcall_or_jmp(int docall) · 314 unmodified lines
387387 R_RISCV_CALL_PLT, (int)vtop->c.i);
388388 o(0x17 | (tr << 7)); // auipc TR, 0 %call(func)
389389 EI(0x67, 0, tr, tr, 0);// jalr TR, r(TR)
390−#ifdef CONFIG_TCC_BCHECK
391− if (tcc_state->do_bounds_check &&
392− (vtop->sym->v == TOK_setjmp ||
393− vtop->sym->v == TOK__setjmp ||
394− vtop->sym->v == TOK_sigsetjmp ||
395− vtop->sym->v == TOK___sigsetjmp))
396− func_bound_add_epilog = 1;
397−#endif
398390 } else if (vtop->r < VT_CONST) {
399391 int r = ireg(vtop->r);
400392 EI(0x67, 0, tr, r, 0); // jalr TR, 0(R)
tcc.h+1−1
@@ -643,7 +643,6 @@ typedef struct AttributeDef { · 642 unmodified lines
643643 struct FuncAttr f;
644644 struct Section *section;
645645 Sym *cleanup_func;
646− int alias_target; /* token */
647646 int asm_label; /* associated asm label */
648647 char attr_mode; /* __attribute__((__mode__(...))) */
649648 } AttributeDef;
@@ -1475,6 +1474,7 @@ ST_FUNC int classify_x86_64_va_arg(CType *ty); · 825 unmodified lines
14751474 #endif
14761475 #ifdef CONFIG_TCC_BCHECK
14771476 ST_FUNC void gbound_args(int nb_args);
1477+ST_DATA int func_bound_add_epilog;
14781478 #endif
14791479
14801480 /* ------------ tccelf.c ------------ */
tccgen.c+71−317
@@ -80,7 +80,7 @@ ST_DATA int func_var; /* true if current function is variadic (used by return in · 79 unmodified lines
8080 ST_DATA int func_vc;
8181 static int last_line_num, new_file, func_ind; /* debug info control */
8282 ST_DATA const char *funcname;
83−ST_DATA CType int_type, func_old_type, char_pointer_type;
83+ST_DATA CType int_type, func_old_type, char_type, char_pointer_type;
8484 static CString initstr;
8585
8686 #if PTR_SIZE == 4
@@ -771,8 +771,13 @@ ST_FUNC void tccgen_init(TCCState *s1) · 684 unmodified lines
771771
772772 /* define some often used types */
773773 int_type.t = VT_INT;
774− char_pointer_type.t = VT_BYTE;
774+
775+ char_type.t = VT_BYTE;
776+ if (s1->char_is_unsigned)
777+ char_type.t |= VT_UNSIGNED;
778+ char_pointer_type = char_type;
775779 mk_pointer(&char_pointer_type);
780+
776781 func_old_type.t = VT_FUNC;
777782 func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
778783 func_old_type.ref->f.func_call = FUNC_CDECL;
@@ -886,66 +891,9 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, · 107 unmodified lines
886891 ElfSym *esym;
887892 const char *name;
888893 char buf1[256];
889−#ifdef CONFIG_TCC_BCHECK
890− char buf[32];
891−#endif
894+
892895 if (!sym->c) {
893896 name = get_tok_str(sym->v, NULL);
894−#ifdef CONFIG_TCC_BCHECK
895− if (tcc_state->do_bounds_check) {
896− /* XXX: avoid doing that for statics ? */
897− /* if bound checking is activated, we change some function
898− names by adding the "__bound" prefix */
899−#if defined(TCC_TARGET_ARM) && defined(TCC_ARM_EABI)
900− if (strcmp (name, "memcpy") == 0 ||
901− strcmp (name, "memmove") == 0 ||
902− strcmp (name, "memset") == 0)
903− goto add_bound;
904−#endif
905− switch(sym->v) {
906−#ifdef TCC_TARGET_PE
907− /* XXX: we rely only on malloc hooks */
908− case TOK_malloc:
909− case TOK_free:
910− case TOK_realloc:
911− case TOK_memalign:
912− case TOK_calloc:
913−#endif
914− case TOK_memcpy:
915− case TOK_memmove:
916−#if defined(TCC_TARGET_ARM) && defined(TCC_ARM_EABI)
917− case TOK_memmove4:
918− case TOK_memmove8:
919−#endif
920− case TOK_memset:
921− case TOK_memcmp:
922− case TOK_strlen:
923− case TOK_strcpy:
924− case TOK_strncpy:
925− case TOK_strcmp:
926− case TOK_strncmp:
927− case TOK_strcat:
928− case TOK_strchr:
929− case TOK_strdup:
930−#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
931− case TOK_alloca:
932−#endif
933− case TOK_mmap:
934− case TOK_munmap:
935− case TOK_longjmp:
936−#ifndef TCC_TARGET_PE
937− case TOK_siglongjmp:
938−#endif
939−#if defined(TCC_TARGET_ARM) && defined(TCC_ARM_EABI)
940−add_bound:
941−#endif
942− strcpy(buf, "__bound_");
943− strcat(buf, name);
944− name = buf;
945− break;
946− }
947− }
948−#endif
949897 t = sym->type.t;
950898 if ((t & VT_BTYPE) == VT_FUNC) {
951899 sym_type = STT_FUNC;
@@ -959,6 +907,7 @@ add_bound: · 7 unmodified lines
959907 else
960908 sym_bind = STB_GLOBAL;
961909 other = 0;
910+
962911 #ifdef TCC_TARGET_PE
963912 if (sym_type == STT_FUNC && sym->type.ref) {
964913 Sym *ref = sym->type.ref;
@@ -973,13 +922,20 @@ add_bound: · 8 unmodified lines
973922 }
974923 }
975924 #endif
925+
926+ if (sym->asm_label) {
927+ name = get_tok_str(sym->asm_label & ~SYM_FIELD, NULL);
928+ /* with SYM_FIELD it was __attribute__((alias("..."))) actually */
929+ if (!(sym->asm_label & SYM_FIELD))
930+ can_add_underscore = 0;
931+ }
932+
976933 if (tcc_state->leading_underscore && can_add_underscore) {
977934 buf1[0] = '_';
978935 pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
979936 name = buf1;
980937 }
981− if (sym->asm_label)
982− name = get_tok_str(sym->asm_label, NULL);
938+
983939 info = ELFW(ST_INFO)(sym_bind, sym_type);
984940 sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name);
985941
@@ -1553,8 +1509,6 @@ static void merge_attr(AttributeDef *ad, AttributeDef *ad1) · 567 unmodified lines
15531509
15541510 if (ad1->section)
15551511 ad->section = ad1->section;
1556− if (ad1->alias_target)
1557− ad->alias_target = ad1->alias_target;
15581512 if (ad1->asm_label)
15591513 ad->asm_label = ad1->asm_label;
15601514 if (ad1->attr_mode)
@@ -1940,13 +1894,34 @@ static void gbound(void) · 379 unmodified lines
19401894 args into registers */
19411895 ST_FUNC void gbound_args(int nb_args)
19421896 {
1943− int i;
1897+ int i, v;
1898+ SValue *sv;
1899+
19441900 for (i = 1; i <= nb_args; ++i)
19451901 if (vtop[1 - i].r & VT_MUSTBOUND) {
19461902 vrotb(i);
19471903 gbound();
19481904 vrott(i);
19491905 }
1906+
1907+ sv = vtop - nb_args;
1908+ if (sv->r & VT_SYM) {
1909+ v = sv->sym->v;
1910+ if (v == TOK_setjmp
1911+ || v == TOK__setjmp
1912+#ifndef TCC_TARGET_PE
1913+ || v == TOK_sigsetjmp
1914+ || v == TOK___sigsetjmp
1915+#endif
1916+ ) {
1917+ vpush_global_sym(&func_old_type, TOK___bound_setjmp);
1918+ vpushv(sv + 1);
1919+ gfunc_call(1);
1920+ func_bound_add_epilog = 1;
1921+ }
1922+ if (v == TOK_alloca)
1923+ func_bound_add_epilog = 1;
1924+ }
19501925 }
19511926
19521927 /* Add bounds for local symbols from S to E (via ->prev) */
@@ -4099,8 +4074,8 @@ redo: · 2146 unmodified lines
40994074 case TOK_ALIAS2:
41004075 skip('(');
41014076 parse_mult_str(&astr, "alias(\"target\")");
4102− ad->alias_target = /* save string as token, for later */
4103− tok_alloc((char*)astr.data, astr.size-1)->tok;
4077+ ad->asm_label = /* save string as token, for later */
4078+ tok_alloc((char*)astr.data, astr.size-1)->tok | SYM_FIELD;
41044079 skip(')');
41054080 cstr_free(&astr);
41064081 break;
@@ -5365,43 +5340,39 @@ static void parse_builtin_params(int nc, const char *args) · 1258 unmodified lines
53655340 while ((c = *args++)) {
53665341 skip(sep);
53675342 sep = ',';
5343+ if (c == 't') {
5344+ parse_type(&type);
5345+ vpush(&type);
5346+ continue;
5347+ }
5348+ expr_eq();
5349+ type.ref = NULL;
5350+ type.t = 0;
53685351 switch (c) {
5369− case 'e': expr_eq();
5370− continue;
5371− case 't': parse_type(&type);
5372− vpush(&type);
5373− continue;
5352+ case 'e':
5353+ continue;
5354+ case 'V':
5355+ type.t = VT_CONSTANT;
53745356 case 'v':
5375− case 'V': expr_eq();
5376− type.t = VT_VOID;
5377− if (c == 'V') type.t |= VT_CONSTANT;
5378− type.ref = NULL;
5379− mk_pointer (&type);
5380− gen_assign_cast(&type);
5381− continue;
5357+ type.t |= VT_VOID;
5358+ mk_pointer (&type);
5359+ break;
5360+ case 'S':
5361+ type.t = VT_CONSTANT;
53825362 case 's':
5383− case 'S': expr_eq();
5384− type.t = VT_BYTE;
5385− if (tcc_state->char_is_unsigned)
5386− type.t |= VT_UNSIGNED;
5387− if (c == 'S') type.t |= VT_CONSTANT;
5388− type.ref = NULL;
5389− mk_pointer (&type);
5390− gen_assign_cast(&type);
5391− continue;
5392− case 'i': expr_eq();
5393− type.t = VT_INT;
5394− type.ref = NULL;
5395− gen_assign_cast(&type);
5396− continue;
5397− case 'l': expr_eq();
5398− type.t = VT_SIZE_T;
5399− type.ref = NULL;
5400− gen_assign_cast(&type);
5401− continue;
5402− default: tcc_error("internal error");
5403− break;
5363+ type.t |= char_type.t;
5364+ mk_pointer (&type);
5365+ break;
5366+ case 'i':
5367+ type.t = VT_INT;
5368+ break;
5369+ case 'l':
5370+ type.t = VT_SIZE_T;
5371+ break;
5372+ default:
5373+ tcc_error("internal error");
54045374 }
5375+ gen_assign_cast(&type);
54055376 }
54065377 skip(')');
54075378 if (nc)
@@ -5780,196 +5751,6 @@ ST_FUNC void unary(void) · 372 unmodified lines
57805751 break;
57815752 }
57825753 #endif
5783− case TOK___builtin_abort:
5784− vpush_global_sym(&func_old_type, TOK_abort);
5785− parse_builtin_params(0, "");
5786− gfunc_call(0);
5787−builtin_void_return:
5788− vpushi(0);
5789− type.t = VT_VOID;
5790− type.ref = NULL;
5791− vtop->type = type;
5792− vtop->r = R_RET(type.t);
5793− break;
5794− case TOK___builtin_memcpy:
5795− t = TOK_memcpy;
5796−#ifdef CONFIG_TCC_BCHECK
5797− if (tcc_state->do_bounds_check) t = TOK___bound_memcpy;
5798−#endif
5799− vpush_global_sym(&func_old_type, t);
5800− parse_builtin_params(0, "vVl");
5801− gfunc_call(3);
5802−builtin_void_ptr_return:
5803− vpushi(0);
5804− type.t = VT_VOID;
5805− type.ref = NULL;
5806− mk_pointer (&type);
5807− vtop->type = type;
5808− vtop->r = R_RET(type.t);
5809− break;
5810− case TOK___builtin_memcmp:
5811− t = TOK_memcmp;
5812−#ifdef CONFIG_TCC_BCHECK
5813− if (tcc_state->do_bounds_check) t = TOK___bound_memcmp;
5814−#endif
5815− vpush_global_sym(&func_old_type, t);
5816− parse_builtin_params(0, "VVl");
5817− gfunc_call(3);
5818−builtin_int_return:
5819− vpushi(0);
5820− type.t = VT_INT;
5821− type.ref = NULL;
5822− vtop->type = type;
5823− vtop->r = R_RET(type.t);
5824− break;
5825− case TOK___builtin_memmove:
5826− t = TOK_memmove;
5827−#ifdef CONFIG_TCC_BCHECK
5828− if (tcc_state->do_bounds_check) t = TOK___bound_memmove;
5829−#endif
5830− vpush_global_sym(&func_old_type, t);
5831− parse_builtin_params(0, "vVl");
5832− gfunc_call(3);
5833− goto builtin_void_ptr_return;
5834− case TOK___builtin_memset:
5835− t = TOK_memset;
5836−#ifdef CONFIG_TCC_BCHECK
5837− if (tcc_state->do_bounds_check) t = TOK___bound_memset;
5838−#endif
5839− vpush_global_sym(&func_old_type, t);
5840− parse_builtin_params(0, "vil");
5841− gfunc_call(3);
5842− goto builtin_void_ptr_return;
5843− case TOK___builtin_strlen:
5844− t = TOK_strlen;
5845−#ifdef CONFIG_TCC_BCHECK
5846− if (tcc_state->do_bounds_check) t = TOK___bound_strlen;
5847−#endif
5848− vpush_global_sym(&func_old_type, t);
5849− parse_builtin_params(0, "S");
5850− gfunc_call(1);
5851− vpushi(0);
5852− type.t = VT_SIZE_T;
5853− type.ref = NULL;
5854− vtop->type = type;
5855− vtop->r = R_RET(type.t);
5856− break;
5857− case TOK___builtin_strcpy:
5858− t = TOK_strcpy;
5859−#ifdef CONFIG_TCC_BCHECK
5860− if (tcc_state->do_bounds_check) t = TOK___bound_strcpy;
5861−#endif
5862− vpush_global_sym(&func_old_type, t);
5863− parse_builtin_params(0, "sS");
5864− gfunc_call(2);
5865−builtin_string_ptr_return:
5866− vpushi(0);
5867− type.t = VT_BYTE;
5868− if (tcc_state->char_is_unsigned)
5869− type.t |= VT_UNSIGNED;
5870− type.ref = NULL;
5871− mk_pointer (&type);
5872− vtop->type = type;
5873− vtop->r = R_RET(type.t);
5874− break;
5875− case TOK___builtin_strncpy:
5876− t = TOK_strncpy;
5877−#ifdef CONFIG_TCC_BCHECK
5878− if (tcc_state->do_bounds_check) t = TOK___bound_strncpy;
5879−#endif
5880− vpush_global_sym(&func_old_type, t);
5881− parse_builtin_params(0, "sSl");
5882− gfunc_call(3);
5883− goto builtin_string_ptr_return;
5884− case TOK___builtin_strcmp:
5885− t = TOK_strcmp;
5886−#ifdef CONFIG_TCC_BCHECK
5887− if (tcc_state->do_bounds_check) t = TOK___bound_strcmp;
5888−#endif
5889− vpush_global_sym(&func_old_type, t);
5890− parse_builtin_params(0, "SS");
5891− gfunc_call(2);
5892− goto builtin_int_return;
5893− case TOK___builtin_strncmp:
5894− t = TOK_strncmp;
5895−#ifdef CONFIG_TCC_BCHECK
5896− if (tcc_state->do_bounds_check) t = TOK___bound_strncmp;
5897−#endif
5898− vpush_global_sym(&func_old_type, t);
5899− parse_builtin_params(0, "SSl");
5900− gfunc_call(3);
5901− goto builtin_int_return;
5902− case TOK___builtin_strcat:
5903− t = TOK_strcat;
5904−#ifdef CONFIG_TCC_BCHECK
5905− if (tcc_state->do_bounds_check) t = TOK___bound_strcat;
5906−#endif
5907− vpush_global_sym(&func_old_type, t);
5908− parse_builtin_params(0, "sS");
5909− gfunc_call(2);
5910− goto builtin_string_ptr_return;
5911− case TOK___builtin_strchr:
5912− t = TOK_strchr;
5913−#ifdef CONFIG_TCC_BCHECK
5914− if (tcc_state->do_bounds_check) t = TOK___bound_strchr;
5915−#endif
5916− vpush_global_sym(&func_old_type, t);
5917− parse_builtin_params(0, "Si");
5918− gfunc_call(2);
5919− goto builtin_string_ptr_return;
5920− case TOK___builtin_strdup:
5921− t = TOK_strdup;
5922−#ifdef CONFIG_TCC_BCHECK
5923− if (tcc_state->do_bounds_check) t = TOK___bound_strdup;
5924−#endif
5925− vpush_global_sym(&func_old_type, t);
5926− parse_builtin_params(0, "S");
5927− gfunc_call(1);
5928− goto builtin_string_ptr_return;
5929− case TOK___builtin_malloc:
5930− t = TOK_malloc;
5931−#if defined(CONFIG_TCC_BCHECK) && defined(TCC_TARGET_PE)
5932− if (tcc_state->do_bounds_check) t = TOK___bound_malloc;
5933−#endif
5934− vpush_global_sym(&func_old_type, t);
5935− parse_builtin_params(0, "l");
5936− gfunc_call(1);
5937− goto builtin_void_ptr_return;
5938− case TOK___builtin_realloc:
5939− t = TOK_realloc;
5940−#if defined(CONFIG_TCC_BCHECK) && defined(TCC_TARGET_PE)
5941− if (tcc_state->do_bounds_check) t = TOK___bound_realloc;
5942−#endif
5943− vpush_global_sym(&func_old_type, t);
5944− parse_builtin_params(0, "vl");
5945− gfunc_call(2);
5946− goto builtin_void_ptr_return;
5947− case TOK___builtin_calloc:
5948− t = TOK_calloc;
5949−#if defined(CONFIG_TCC_BCHECK) && defined(TCC_TARGET_PE)
5950− if (tcc_state->do_bounds_check) t = TOK___bound_calloc;
5951−#endif
5952− vpush_global_sym(&func_old_type, t);
5953− parse_builtin_params(0, "ll");
5954− gfunc_call(2);
5955− goto builtin_void_ptr_return;
5956− case TOK___builtin_free:
5957− t = TOK_free;
5958−#if defined(CONFIG_TCC_BCHECK) && defined(TCC_TARGET_PE)
5959− if (tcc_state->do_bounds_check) t = TOK___bound_free;
5960−#endif
5961− vpush_global_sym(&func_old_type, t);
5962− parse_builtin_params(0, "v");
5963− gfunc_call(1);
5964− goto builtin_void_return;
5965−#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
5966− case TOK_alloca:
5967− case TOK___builtin_alloca:
5968− vpush_global_sym(&func_old_type, TOK_alloca);
5969− parse_builtin_params(0, "l");
5970− gfunc_call(1);
5971− goto builtin_void_ptr_return;
5972−#endif
59735754
59745755 /* pre operations */
59755756 case TOK_INC:
@@ -6276,24 +6057,6 @@ special_math_val: · 300 unmodified lines
62766057 if (sa)
62776058 tcc_error("too few arguments to function");
62786059 skip(')');
6279−#ifdef CONFIG_TCC_BCHECK
6280− if (tcc_state->do_bounds_check &&
6281− (nb_args == 1 || nb_args == 2) &&
6282− (vtop[-nb_args].r & VT_SYM) &&
6283− (vtop[-nb_args].sym->v == TOK_setjmp ||
6284− vtop[-nb_args].sym->v == TOK__setjmp
6285−#ifndef TCC_TARGET_PE
6286− || vtop[-nb_args].sym->v == TOK_sigsetjmp
6287− || vtop[-nb_args].sym->v == TOK___sigsetjmp
6288−#endif
6289− )) {
6290− vpush_global_sym(&func_old_type, TOK___bound_setjmp);
6291− vpushv(vtop - nb_args);
6292− if (nb_args == 2)
6293− vpushv(vtop - nb_args);
6294− gfunc_call(nb_args);
6295− }
6296−#endif
62976060 gfunc_call(nb_args);
62986061
62996062 if (ret_nregs < 0) {
@@ -8602,15 +8365,6 @@ found: · 2302 unmodified lines
86028365 /* external variable or function */
86038366 type.t |= VT_EXTERN;
86048367 sym = external_sym(v, &type, r, &ad);
8605− if (ad.alias_target) {
8606− ElfSym *esym;
8607− Sym *alias_target;
8608− alias_target = sym_find(ad.alias_target);
8609− esym = elfsym(alias_target);
8610− if (!esym)
8611− tcc_error("unsupported forward __alias__ attribute");
8612− put_extern_sym2(sym, esym->st_shndx, esym->st_value, esym->st_size, 0);
8613− }
86148368 } else {
86158369 if (type.t & VT_STATIC)
86168370 r |= VT_CONST;
tccpp.c+52−7
@@ -3625,10 +3625,13 @@ ST_INLN void unget_tok(int last_tok) · 3624 unmodified lines
36253625 static void tcc_predefs(CString *cstr)
36263626 {
36273627 cstr_cat(cstr,
3628+
3629+ //"#include <tcc_predefs.h>\n"
3630+
36283631 #if defined TCC_TARGET_X86_64
36293632 #ifndef TCC_TARGET_PE
3630− /* GCC compatible definition of va_list. This should be in sync
3631− with the declaration in our lib/libtcc1.c */
3633+ /* GCC compatible definition of va_list. */
3634+ /* This should be in sync with the declaration in our lib/libtcc1.c */
36323635 "typedef struct{\n"
36333636 "unsigned gp_offset,fp_offset;\n"
36343637 "union{\n"
@@ -3644,7 +3647,6 @@ static void tcc_predefs(CString *cstr) · 9 unmodified lines
36443647 #else /* TCC_TARGET_PE */
36453648 "typedef char*__builtin_va_list;\n"
36463649 "#define __builtin_va_arg(ap,t) ((sizeof(t)>8||(sizeof(t)&(sizeof(t)-1)))?**(t**)((ap+=8)-8):*(t*)((ap+=8)-8))\n"
3647− "#define __builtin_va_copy(dest,src) (dest)=(src)\n"
36483650 #endif
36493651 #elif defined TCC_TARGET_ARM
36503652 "typedef char*__builtin_va_list;\n"
@@ -3652,26 +3654,69 @@ static void tcc_predefs(CString *cstr) · 1 unmodified line
36523654 "#define _tcc_align(addr,type) (((unsigned)addr+_tcc_alignof(type)-1)&~(_tcc_alignof(type)-1))\n"
36533655 "#define __builtin_va_start(ap,last) (ap=((char*)&(last))+((sizeof(last)+3)&~3))\n"
36543656 "#define __builtin_va_arg(ap,type) (ap=(void*)((_tcc_align(ap,type)+sizeof(type)+3)&~3),*(type*)(ap-((sizeof(type)+3)&~3)))\n"
3655− "#define __builtin_va_copy(dest,src) (dest)=(src)\n"
36563657 #elif defined TCC_TARGET_ARM64
36573658 "typedef struct{\n"
36583659 "void*__stack,*__gr_top,*__vr_top;\n"
36593660 "int __gr_offs,__vr_offs;\n"
36603661 "}__builtin_va_list;\n"
3661− "#define __builtin_va_copy(dest,src) (dest)=(src)\n"
36623662 #elif defined TCC_TARGET_RISCV64
36633663 "typedef char*__builtin_va_list;\n"
36643664 "#define __va_reg_size (__riscv_xlen>>3)\n"
36653665 "#define _tcc_align(addr,type) (((unsigned long)addr+__alignof__(type)-1)&-(__alignof__(type)))\n"
36663666 "#define __builtin_va_arg(ap,type) (*(sizeof(type)>(2*__va_reg_size)?*(type**)((ap+=__va_reg_size)-__va_reg_size):(ap=(va_list)(_tcc_align(ap,type)+(sizeof(type)+__va_reg_size-1)&-__va_reg_size),(type*)(ap-((sizeof(type)+__va_reg_size-1)&-__va_reg_size)))))\n"
3667− "#define __builtin_va_copy(dest,src) (dest)=(src)\n"
36683667 #else /* TCC_TARGET_I386 */
36693668 "typedef char*__builtin_va_list;\n"
36703669 "#define __builtin_va_start(ap,last) (ap=((char*)&(last))+((sizeof(last)+3)&~3))\n"
36713670 "#define __builtin_va_arg(ap,t) (*(t*)((ap+=(sizeof(t)+3)&~3)-((sizeof(t)+3)&~3)))\n"
3672− "#define __builtin_va_copy(dest,src) (dest)=(src)\n"
36733671 #endif
36743672 "#define __builtin_va_end(ap) (void)(ap)\n"
3673+ "#ifndef __builtin_va_copy\n"
3674+ "#define __builtin_va_copy(dest,src) (dest)=(src)\n"
3675+ "#endif\n"
3676+ /* TCC BBUILTIN AND BOUNDS ALIASES */
3677+ "#ifdef __BOUNDS_CHECKING_ON\n"
3678+ "#define __BUILTIN(ret,name,params) ret __builtin_##name params __attribute__((alias(\"__bound_\"#name)));\n"
3679+ "#define __BOUND(ret,name,params) ret name params __attribute__((alias(\"__bound_\"#name)));\n"
3680+ "#else\n"
3681+ "#define __BUILTIN(ret,name,params) ret __builtin_##name params __attribute__((alias(#name)));\n"
3682+ "#define __BOUND(ret,name,params)\n"
3683+ "#endif\n"
3684+ "#define __BOTH(ret,name,params) __BUILTIN(ret,name,params)__BOUND(ret,name,params)\n"
3685+ "__BOTH(void*,memcpy,(void*,const void*,__SIZE_TYPE__))\n"
3686+ "__BOTH(void*,memmove,(void*,const void*,__SIZE_TYPE__))\n"
3687+ "__BOTH(void*,memset,(void*,int,__SIZE_TYPE__))\n"
3688+ "__BOTH(int,memcmp,(const void*,const void*,__SIZE_TYPE__))\n"
3689+ "__BOTH(__SIZE_TYPE__,strlen,(const char*))\n"
3690+ "__BOTH(char*,strcpy,(char*,const char*))\n"
3691+ "__BOTH(char*,strncpy,(char*,const char*,__SIZE_TYPE__))\n"
3692+ "__BOTH(int,strcmp,(const char*,const char*))\n"
3693+ "__BOTH(int,strncmp,(const char*,const char*,__SIZE_TYPE__))\n"
3694+ "__BOTH(char*,strcat,(char*,const char*))\n"
3695+ "__BOTH(char*,strchr,(const char*,int))\n"
3696+ "__BOTH(char*,strdup,(const char*))\n"
3697+#ifdef TCC_TARGET_PE
3698+ "#define __MAYBE_REDIR __BOTH\n"
3699+#else // HAVE MALLOC_REDIR
3700+ "#define __MAYBE_REDIR __BUILTIN\n"
3701+#endif
3702+ "__MAYBE_REDIR(void*,malloc,(__SIZE_TYPE__))\n"
3703+ "__MAYBE_REDIR(void*,realloc,(void*,__SIZE_TYPE__))\n"
3704+ "__MAYBE_REDIR(void*,calloc,(__SIZE_TYPE__,__SIZE_TYPE__))\n"
3705+ "__MAYBE_REDIR(void*,memalign,(__SIZE_TYPE__,__SIZE_TYPE__))\n"
3706+ "__MAYBE_REDIR(void,free,(void*))\n"
3707+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
3708+ "__BOTH(void*,alloca,(__SIZE_TYPE__))\n"
3709+#endif
3710+ "__BUILTIN(void,abort,(void))\n"
3711+ "__BOUND(int,longjmp,())\n"
3712+#ifndef TCC_TARGET_PE
3713+ "__BOUND(void*,mmap,())\n"
3714+ "__BOUND(void*,munmap,())\n"
3715+#endif
3716+ "#undef __BUILTIN\n"
3717+ "#undef __BOUND\n"
3718+ "#undef __BOTH\n"
3719+ "#undef __MAYBE_REDIR\n"
36753720 , -1);
36763721 }
36773722
tcctok.h+0−55
@@ -314,68 +314,13 @@ · 313 unmodified lines
314314 # ifdef TCC_TARGET_X86_64
315315 DEF(TOK___bound_alloca_nr, "__bound_alloca_nr")
316316 # endif
317− DEF(TOK_memalign, "memalign")
318317 # else
319318 DEF(TOK_sigsetjmp, "sigsetjmp")
320319 DEF(TOK___sigsetjmp, "__sigsetjmp")
321320 DEF(TOK_siglongjmp, "siglongjmp")
322321 # endif
323− DEF(TOK_mmap, "mmap")
324− DEF(TOK_munmap, "munmap")
325322 DEF(TOK_setjmp, "setjmp")
326323 DEF(TOK__setjmp, "_setjmp")
327− DEF(TOK_longjmp, "longjmp")
328− DEF(TOK___bound_memcpy, "__bound_memcpy")
329− DEF(TOK___bound_memcmp, "__bound_memcmp")
330− DEF(TOK___bound_memmove, "__bound_memmove")
331− DEF(TOK___bound_memset, "__bound_memset")
332− DEF(TOK___bound_strlen, "__bound_strlen")
333− DEF(TOK___bound_strcpy, "__bound_strcpy")
334− DEF(TOK___bound_strncpy, "__bound_strncpy")
335− DEF(TOK___bound_strcmp, "__bound_strcmp")
336− DEF(TOK___bound_strncmp, "__bound_strncmp")
337− DEF(TOK___bound_strcat, "__bound_strcat")
338− DEF(TOK___bound_strchr, "__bound_strchr")
339− DEF(TOK___bound_strdup, "__bound_strdup")
340− DEF(TOK___bound_malloc, "__bound_malloc")
341− DEF(TOK___bound_free, "__bound_free")
342− DEF(TOK___bound_realloc, "__bound_realloc")
343− DEF(TOK___bound_calloc, "__bound_calloc")
344−#endif
345− DEF(TOK_abort, "abort")
346− DEF(TOK_memcmp, "memcmp")
347− DEF(TOK_strlen, "strlen")
348− DEF(TOK_strcpy, "strcpy")
349− DEF(TOK_strncpy, "strncpy")
350− DEF(TOK_strcmp, "strcmp")
351− DEF(TOK_strncmp, "strncmp")
352− DEF(TOK_strcat, "strcat")
353− DEF(TOK_strchr, "strchr")
354− DEF(TOK_strdup, "strdup")
355− DEF(TOK_malloc, "malloc")
356− DEF(TOK_free, "free")
357− DEF(TOK_realloc, "realloc")
358− DEF(TOK_calloc, "calloc")
359−
360− DEF(TOK___builtin_abort, "__builtin_abort")
361− DEF(TOK___builtin_memcpy, "__builtin_memcpy")
362− DEF(TOK___builtin_memcmp, "__builtin_memcmp")
363− DEF(TOK___builtin_memmove, "__builtin_memmove")
364− DEF(TOK___builtin_memset, "__builtin_memset")
365− DEF(TOK___builtin_strlen, "__builtin_strlen")
366− DEF(TOK___builtin_strcpy, "__builtin_strcpy")
367− DEF(TOK___builtin_strncpy, "__builtin_strncpy")
368− DEF(TOK___builtin_strcmp, "__builtin_strcmp")
369− DEF(TOK___builtin_strncmp, "__builtin_strncmp")
370− DEF(TOK___builtin_strcat, "__builtin_strcat")
371− DEF(TOK___builtin_strchr, "__builtin_strchr")
372− DEF(TOK___builtin_strdup, "__builtin_strdup")
373− DEF(TOK___builtin_malloc, "__builtin_malloc")
374− DEF(TOK___builtin_free, "__builtin_free")
375− DEF(TOK___builtin_realloc, "__builtin_realloc")
376− DEF(TOK___builtin_calloc, "__builtin_calloc")
377−#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
378− DEF(TOK___builtin_alloca, "__builtin_alloca")
379324 #endif
380325
381326 /* Tiny Assembler */
tests/misc/c2str.c+112−0
@@ -0,0 +1,112 @@
1+#include <stdio.h>
2+#include <string.h>
3+
4+int isid(int c)
5+{
6+ return (c >= 'a' && c <= 'z')
7+ || (c >= 'A' && c <= 'Z')
8+ || (c >= '0' && c <= '9')
9+ || c == '_';
10+}
11+
12+int isspc(int c)
13+{
14+ return c == ' ' || c == '\t';
15+}
16+
17+int main(int argc, char **argv)
18+{
19+ char l[1000], *p, l2[1000], *q;
20+ FILE *fp, *op;
21+ int c, e, f;
22+
23+ if (argc < 3)
24+ return 1;
25+
26+ fp = fopen(argv[1], "rb");
27+ op = fopen(argv[2], "wb");
28+ if (!fp || !op) {
29+ fprintf(stderr, "c2str: file error\n");
30+ return 1;
31+ }
32+
33+ for (;;) {
34+ p = l;
35+ append:
36+ if (fgets(p, sizeof l - (p - l), fp)) {
37+ p = strchr(p, 0);
38+ while (p > l && p[-1] == '\n')
39+ --p;
40+ *p = 0;
41+ } else if (p == l)
42+ break;
43+ if (p > l && p[-1] == '\\') {
44+ --p;
45+ goto append;
46+ }
47+
48+ if (l[0] == 0)
49+ continue;
50+ p = l, q = l2, f = e = 0;
51+ while (*p && isspc(*p))
52+ ++p, ++f;
53+
54+ if (f < 4) {
55+ do {
56+ static const char *sr[] = {
57+ "__x86_64__", "TCC_TARGET_X86_64",
58+ "_WIN64", "TCC_TARGET_PE",
59+ "_WIN32", "TCC_TARGET_PE",
60+ "__arm__", "TCC_TARGET_ARM",
61+ "__aarch64__", "TCC_TARGET_ARM64",
62+ "__riscv", "TCC_TARGET_RISCV64",
63+ "__i386__", "TCC_TARGET_I386", 0 };
64+ for (f = 0; sr[f]; f += 2) {
65+ c = strlen(sr[f]);
66+ if (0 == memcmp(p, sr[f], c)) {
67+ p += c, ++f;
68+ q = strchr(strcpy(q, sr[f]), 0);
69+ break;
70+ }
71+
72+ }
73+ if (sr[f])
74+ continue;
75+ } while (!!(*q++ = *p++));
76+
77+ fprintf(op, "%s\n", l2);
78+
79+ } else if (*p == '/') {
80+ strcpy(q, p);
81+ fprintf(op, " %s\n", l2);
82+
83+ } else {
84+ f = 0;
85+ for (;;) {
86+ c = *p++;
87+ if (isspc(c)) {
88+ if (q == l2 || isspc(q[-1]))
89+ continue;
90+ if ((f > 2 || e) || (q[-1] != ')' && *p != '(')) {
91+ if (!isid(q[-1]) || !isid(*p))
92+ continue;
93+ }
94+ }
95+ if (c == '(')
96+ ++e, ++f;
97+ if (c == ')')
98+ --e, ++f;
99+ if (c == '\\' || c == '\"')
100+ *q++ = '\\';
101+ *q++ = c;
102+ if (c == 0)
103+ break;
104+ }
105+ fprintf(op, " \"%s\\n\"\n", l2);
106+ }
107+ }
108+
109+ fclose(fp);
110+ fclose(op);
111+ return 0;
112+}
tests/misc/tcc_predefs.h+111−0
@@ -0,0 +1,111 @@
1+#if defined __x86_64__
2+#ifndef _WIN64
3+ /* GCC compatible definition of va_list. */
4+ /* This should be in sync with the declaration in our lib/libtcc1.c */
5+ typedef struct {
6+ unsigned gp_offset, fp_offset;
7+ union {
8+ unsigned overflow_offset;
9+ char *overflow_arg_area;
10+ };
11+ char *reg_save_area;
12+ } __builtin_va_list[1];
13+
14+ void *__va_arg(__builtin_va_list ap, int arg_type, int size, int align);
15+ #define __builtin_va_start(ap, last) \
16+ (*(ap) = *(__builtin_va_list)((char*)__builtin_frame_address(0) - 24))
17+ #define __builtin_va_arg(ap, t) \
18+ (*(t *)(__va_arg(ap, __builtin_va_arg_types(t), sizeof(t), __alignof__(t))))
19+ #define __builtin_va_copy(dest, src) (*(dest) = *(src))
20+
21+#else /* _WIN64 */
22+ typedef char *__builtin_va_list;
23+ #define __builtin_va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \
24+ ? **(t **)((ap += 8) - 8) : *(t *)((ap += 8) - 8))
25+#endif
26+
27+#elif defined __arm__
28+ typedef char *__builtin_va_list;
29+ #define _tcc_alignof(type) ((int)&((struct {char c;type x;} *)0)->x)
30+ #define _tcc_align(addr,type) (((unsigned)addr + _tcc_alignof(type) - 1) \
31+ & ~(_tcc_alignof(type) - 1))
32+ #define __builtin_va_start(ap,last) (ap = ((char *)&(last)) + ((sizeof(last)+3)&~3))
33+ #define __builtin_va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \
34+ &~3), *(type *)(ap - ((sizeof(type)+3)&~3)))
35+
36+#elif defined __aarch64__
37+ typedef struct {
38+ void *__stack, *__gr_top, *__vr_top;
39+ int __gr_offs, __vr_offs;
40+ } __builtin_va_list;
41+
42+#elif defined __riscv
43+ typedef char *__builtin_va_list;
44+ #define __va_reg_size (__riscv_xlen >> 3)
45+ #define _tcc_align(addr,type) (((unsigned long)addr + __alignof__(type) - 1) \
46+ & -(__alignof__(type)))
47+ #define __builtin_va_arg(ap,type) (*(sizeof(type) > (2*__va_reg_size) ? *(type **)((ap += __va_reg_size) - __va_reg_size) : (ap = (va_list)(_tcc_align(ap,type) + (sizeof(type)+__va_reg_size - 1)& -__va_reg_size), (type *)(ap - ((sizeof(type)+ __va_reg_size - 1)& -__va_reg_size)))))
48+
49+#else /* __i386__ */
50+ typedef char *__builtin_va_list;
51+ #define __builtin_va_start(ap,last) (ap = ((char *)&(last)) + ((sizeof(last)+3)&~3))
52+ #define __builtin_va_arg(ap,t) (*(t*)((ap+=(sizeof(t)+3)&~3)-((sizeof(t)+3)&~3)))
53+
54+#endif
55+ #define __builtin_va_end(ap) (void)(ap)
56+ #ifndef __builtin_va_copy
57+ # define __builtin_va_copy(dest, src) (dest) = (src)
58+ #endif
59+
60+
61+ /* TCC BBUILTIN AND BOUNDS ALIASES */
62+ #ifdef __BOUNDS_CHECKING_ON
63+ # define __BUILTIN(ret,name,params) \
64+ ret __builtin_##name params __attribute__((alias("__bound_" #name)));
65+ # define __BOUND(ret,name,params) \
66+ ret name params __attribute__((alias("__bound_" #name)));
67+ #else
68+ # define __BUILTIN(ret,name,params) \
69+ ret __builtin_##name params __attribute__((alias(#name)));
70+ # define __BOUND(ret,name,params)
71+ #endif
72+ # define __BOTH(ret,name,params) \
73+ __BUILTIN(ret,name,params) __BOUND(ret,name,params)
74+
75+ __BOTH(void*, memcpy, (void *, const void*, __SIZE_TYPE__))
76+ __BOTH(void*, memmove, (void *, const void*, __SIZE_TYPE__))
77+ __BOTH(void*, memset, (void *, int, __SIZE_TYPE__))
78+ __BOTH(int, memcmp, (const void *, const void*, __SIZE_TYPE__))
79+ __BOTH(__SIZE_TYPE__, strlen, (const char *))
80+ __BOTH(char*, strcpy, (char *, const char *))
81+ __BOTH(char*, strncpy, (char *, const char*, __SIZE_TYPE__))
82+ __BOTH(int, strcmp, (const char*, const char*))
83+ __BOTH(int, strncmp, (const char*, const char*, __SIZE_TYPE__))
84+ __BOTH(char*, strcat, (char*, const char*))
85+ __BOTH(char*, strchr, (const char*, int))
86+ __BOTH(char*, strdup, (const char*))
87+
88+#ifdef _WIN32
89+ #define __MAYBE_REDIR __BOTH
90+#else // HAVE MALLOC_REDIR
91+ #define __MAYBE_REDIR __BUILTIN
92+#endif
93+ __MAYBE_REDIR(void*, malloc, (__SIZE_TYPE__))
94+ __MAYBE_REDIR(void*, realloc, (void *, __SIZE_TYPE__))
95+ __MAYBE_REDIR(void*, calloc, (__SIZE_TYPE__, __SIZE_TYPE__))
96+ __MAYBE_REDIR(void*, memalign, (__SIZE_TYPE__, __SIZE_TYPE__))
97+ __MAYBE_REDIR(void, free, (void*))
98+
99+#if defined __i386__ || defined __x86_64__
100+ __BOTH(void*, alloca, (__SIZE_TYPE__))
101+#endif
102+ __BUILTIN(void, abort, (void))
103+ __BOUND(int, longjmp, ())
104+#ifndef _WIN32
105+ __BOUND(void*, mmap, ())
106+ __BOUND(void*, munmap, ())
107+#endif
108+ #undef __BUILTIN
109+ #undef __BOUND
110+ #undef __BOTH
111+ #undef __MAYBE_REDIR
tests/tcctest.c+145−277
@@ -2,10 +2,11 @@ · 1 unmodified line
22 * TCC auto test program
33 */
44 #include "config.h"
5+
6+/* identify the configured reference compiler in use */
57 #define CC_gcc 1
68 #define CC_clang 2
79 #define CC_tcc 3
8−#define CC_msvc 4 /* cannot compile this file */
910
1011 /* Unfortunately, gcc version < 3 does not handle that! */
1112 #define ALL_ISOC99
@@ -13,15 +14,9 @@ · 1 unmodified line
1314 /* only gcc 3 handles _Bool correctly */
1415 #define BOOL_ISOC99
1516
16−/* gcc 2.95.3 does not handle correctly CR in strings or after strays */
17−#define CORRECT_CR_HANDLING
18−
1917 /* __VA_ARGS__ and __func__ support */
2018 #define C99_MACROS
2119
22−/* deprecated and no longer supported in gcc 3.3 */
23−//#define ACCEPT_CR_IN_STRINGS
24−
2520 #ifndef __TINYC__
2621 typedef __SIZE_TYPE__ uintptr_t;
2722 #endif
@@ -81,61 +76,6 @@ typedef __SIZE_TYPE__ uintptr_t; · 53 unmodified lines
8176 #include incname
8277 #include stringify(funnyname)
8378
84−void intdiv_test();
85−void string_test();
86−void expr_test();
87−void macro_test();
88−void recursive_macro_test();
89−void scope_test();
90−void scope_test2();
91−void forward_test();
92−void funcptr_test();
93−void if_test();
94−void loop_test();
95−void switch_test();
96−void goto_test();
97−void enum_test();
98−void typedef_test();
99−void struct_test();
100−void array_test();
101−void expr_ptr_test();
102−void bool_test();
103−void optimize_out();
104−void expr2_test();
105−void constant_expr_test();
106−void expr_cmp_test();
107−void char_short_test();
108−void init_test(void);
109−void compound_literal_test(void);
110−int kr_test();
111−void struct_assign_test(void);
112−void cast_test(void);
113−void bitfield_test(void);
114−void c99_bool_test(void);
115−void float_test(void);
116−void longlong_test(void);
117−void manyarg_test(void);
118−void stdarg_test(void);
119−void whitespace_test(void);
120−void relocation_test(void);
121−void old_style_function(void);
122−void alloca_test(void);
123−void c99_vla_test(int size1, int size2);
124−void sizeof_test(void);
125−void typeof_test(void);
126−void local_label_test(void);
127−void statement_expr_test(void);
128−void asm_test(void);
129−void builtin_test(void);
130−void weak_test(void);
131−void global_data_test(void);
132−void cmp_comparison_test(void);
133−void math_cmp_test(void);
134−void callsave_test(void);
135−void builtin_frame_address_test(void);
136−void attrib_test(void);
137−void bounds_check1_test(void);
138−
13979 int fib(int n);
14080 void num(int n);
14181 void forward_ref(void);
@@ -146,8 +86,6 @@ int isid(int c); · 4 unmodified lines
14686 void funny_line_continuation (int, ..\
14787 . );
14888
149−char via_volatile (char);
150−
15189 #define A 2
15290 #define N 1234 + A
15391 #define pf printf
@@ -207,74 +145,8 @@ int qq(int x) · 53 unmodified lines
207145 #define wq_spin_lock spin_lock
208146 #define TEST2() wq_spin_lock(a)
209147
210−#define UINT_MAX ((unsigned) -1)
211−
212−void intdiv_test(void)
213−{
214− printf("18/21=%u\n", 18/21);
215− printf("18%%21=%u\n", 18%21);
216− printf("41/21=%u\n", 41/21);
217− printf("41%%21=%u\n", 41%21);
218− printf("42/21=%u\n", 42/21);
219− printf("42%%21=%u\n", 42%21);
220− printf("43/21=%u\n", 43/21);
221− printf("43%%21=%u\n", 43%21);
222− printf("126/21=%u\n", 126/21);
223− printf("126%%21=%u\n", 126%21);
224− printf("131/21=%u\n", 131/21);
225− printf("131%%21=%u\n", 131%21);
226− printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2);
227− printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2);
228−
229− printf("18/-21=%u\n", 18/-21);
230− printf("18%%-21=%u\n", 18%-21);
231− printf("41/-21=%u\n", 41/-21);
232− printf("41%%-21=%u\n", 41%-21);
233− printf("42/-21=%u\n", 42/-21);
234− printf("42%%-21=%u\n", 42%-21);
235− printf("43/-21=%u\n", 43/-21);
236− printf("43%%-21=%u\n", 43%-21);
237− printf("126/-21=%u\n", 126/-21);
238− printf("126%%-21=%u\n", 126%-21);
239− printf("131/-21=%u\n", 131/-21);
240− printf("131%%-21=%u\n", 131%-21);
241− printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2);
242− printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2);
243−
244− printf("-18/21=%u\n", -18/21);
245− printf("-18%%21=%u\n", -18%21);
246− printf("-41/21=%u\n", -41/21);
247− printf("-41%%21=%u\n", -41%21);
248− printf("-42/21=%u\n", -42/21);
249− printf("-42%%21=%u\n", -42%21);
250− printf("-43/21=%u\n", -43/21);
251− printf("-43%%21=%u\n", -43%21);
252− printf("-126/21=%u\n", -126/21);
253− printf("-126%%21=%u\n", -126%21);
254− printf("-131/21=%u\n", -131/21);
255− printf("-131%%21=%u\n", -131%21);
256− printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2);
257− printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2);
258−
259− printf("-18/-21=%u\n", -18/-21);
260− printf("-18%%-21=%u\n", -18%-21);
261− printf("-41/-21=%u\n", -41/-21);
262− printf("-41%%-21=%u\n", -41%-21);
263− printf("-42/-21=%u\n", -42/-21);
264− printf("-42%%-21=%u\n", -42%-21);
265− printf("-43/-21=%u\n", -43/-21);
266− printf("-43%%-21=%u\n", -43%-21);
267− printf("-126/-21=%u\n", -126/-21);
268− printf("-126%%-21=%u\n", -126%-21);
269− printf("-131/-21=%u\n", -131/-21);
270− printf("-131%%-21=%u\n", -131%-21);
271− printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2);
272− printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2);
273−}
274−
275148 void macro_test(void)
276149 {
277− printf("macro:\n");
278150 pf("N=%d\n", N);
279151 printf("aaa=%d\n", AAA);
280152
@@ -349,22 +221,6 @@ void macro_test(void) · 68 unmodified lines
349221
350222 MACRO_NOARGS();
351223
352−#ifdef __LINE__
353− printf("__LINE__ defined\n");
354−#endif
355−
356− printf("__LINE__=%d __FILE__=%s\n",
357− __LINE__, __FILE__);
358−#if 0
359−#line 200
360− printf("__LINE__=%d __FILE__=%s\n",
361− __LINE__, __FILE__);
362−#line 203 "test"
363− printf("__LINE__=%d __FILE__=%s\n",
364− __LINE__, __FILE__);
365−#line 227 "tcctest.c"
366−#endif
367−
368224 /* not strictly preprocessor, but we test it there */
369225 #ifdef C99_MACROS
370226 printf("__func__ = %s\n", __func__);
@@ -677,7 +533,7 @@ void goto_test() · 306 unmodified lines
677533 int i;
678534 static void *label_table[3] = { &&label1, &&label2, &&label3 };
679535
680− printf("goto:\n");
536+ printf("\ngoto:\n");
681537 i = 0;
682538 /* This needs to parse as label, not as start of decl. */
683539 typedef_and_label x;
@@ -745,8 +601,7 @@ void enum_test() · 61 unmodified lines
745601 /* The following should give no warning */
746602 unsigned *p = &b1;
747603 struct S_enum s = {E7};
748− printf("enum: %d\n", s.e);
749− printf("enum:\n%d %d %d %d %d %d\n",
604+ printf("%d %d %d %d %d %d %d\n", s.e,
750605 E0, E1, E2, E3, E4, E5);
751606 b1 = 1;
752607 printf("b1=%d\n", b1);
@@ -775,7 +630,6 @@ void typedef_test() · 22 unmodified lines
775630
776631 a = &b;
777632 *a = 1234;
778− printf("typedef:\n");
779633 printf("a=%d\n", *a);
780634 mytype2 = 2;
781635 printf("mytype2=%d\n", mytype2);
@@ -783,7 +637,6 @@ void typedef_test() · 1 unmodified line
783637
784638 void forward_test()
785639 {
786− printf("forward:\n");
787640 forward_ref();
788641 forward_ref();
789642 }
@@ -821,69 +674,6 @@ struct empty_mem { · 31 unmodified lines
821674 int x;
822675 };
823676
824−int main(int argc, char **argv)
825−{
826− string_test();
827− expr_test();
828− macro_test();
829− recursive_macro_test();
830− scope_test();
831− scope_test2();
832− forward_test();
833− funcptr_test();
834− if_test();
835− loop_test();
836− switch_test();
837− goto_test();
838− enum_test();
839− typedef_test();
840− struct_test();
841− array_test();
842− expr_ptr_test();
843− bool_test();
844− optimize_out();
845− expr2_test();
846− constant_expr_test();
847− expr_cmp_test();
848− char_short_test();
849− init_test();
850− compound_literal_test();
851− kr_test();
852− struct_assign_test();
853− cast_test();
854− bitfield_test();
855− c99_bool_test();
856− float_test();
857− longlong_test();
858− manyarg_test();
859− stdarg_test();
860− whitespace_test();
861− relocation_test();
862− old_style_function();
863− alloca_test();
864− c99_vla_test(5, 2);
865− sizeof_test();
866− typeof_test();
867− statement_expr_test();
868− local_label_test();
869− asm_test();
870− builtin_test();
871−#ifndef _WIN32
872− weak_test();
873−#endif
874− global_data_test();
875− cmp_comparison_test();
876− math_cmp_test();
877− callsave_test();
878− builtin_frame_address_test();
879− intdiv_test();
880− if (via_volatile (42) != 42)
881− printf ("via_volatile broken\n");
882− attrib_test();
883− bounds_check1_test();
884− return 0;
885−}
886−
887677 int tab[3];
888678 int tab2[3][2];
889679
@@ -896,7 +686,6 @@ void f1(g) · 6 unmodified lines
896686
897687 void scope_test()
898688 {
899− printf("scope:\n");
900689 g = 2;
901690 f1(1);
902691 printf("g2=%d\n", g);
@@ -915,7 +704,7 @@ void scope_test() · 12 unmodified lines
915704
916705 int st2_i;
917706 int *st2_p = &st2_i;
918−void scope_test2()
707+void scope2_test()
919708 {
920709 char a[50];
921710 st2_i = 42;
@@ -941,7 +730,6 @@ void array_test() · 19 unmodified lines
941730 {
942731 int i, j, a[4];
943732
944− printf("array:\n");
945733 printf("sizeof(a) = %d\n", sizeof(a));
946734 printf("sizeof(\"a\") = %d\n", sizeof("a"));
947735 #ifdef C99_MACROS
@@ -1046,7 +834,6 @@ void expr2_test() · 98 unmodified lines
1046834 {
1047835 int a, b;
1048836
1049− printf("expr2:\n");
1050837 vstack_ptr = vstack;
1051838 vpush(1432432, 2);
1052839 vstack_ptr[-2] &= ~0xffffff80;
@@ -1059,7 +846,6 @@ int const_len_ar[sizeof(1/0)]; /* div-by-zero, but in unevaluated context */ · 6 unmodified lines
1059846 void constant_expr_test()
1060847 {
1061848 int a;
1062− printf("constant_expr:\n");
1063849 a = 3;
1064850 printf("%d\n", a * 16);
1065851 printf("%d\n", a * 1);
@@ -1074,7 +860,6 @@ void expr_ptr_test() · 8 unmodified lines
1074860 int *p, *q;
1075861 int i = -1;
1076862
1077− printf("expr_ptr:\n");
1078863 p = tab4;
1079864 q = tab4 + 10;
1080865 printf("diff=%d\n", q - p);
@@ -1130,7 +915,6 @@ void expr_ptr_test() · 49 unmodified lines
1130915 void expr_cmp_test()
1131916 {
1132917 int a, b;
1133− printf("constant_expr:\n");
1134918 a = -1;
1135919 b = 1;
1136920 printf("%d\n", a == a);
@@ -1250,7 +1034,6 @@ void struct_test() · 113 unmodified lines
12501034 union union2 u;
12511035 struct Large ls;
12521036
1253− printf("struct:\n");
12541037 printf("sizes: %d %d %d %d\n",
12551038 sizeof(struct struct1),
12561039 sizeof(struct struct2),
@@ -1326,8 +1109,6 @@ void char_short_test() · 69 unmodified lines
13261109 signed char var3;
13271110 long long var4;
13281111
1329− printf("char_short:\n");
1330−
13311112 var1 = 0x01020304;
13321113 var2 = 0xfffefdfc;
13331114 printf("s8=%d %d\n",
@@ -1495,7 +1276,7 @@ static inline void refer_to_undefined(void) · 161 unmodified lines
14951276 undefined_function();
14961277 }
14971278
1498−void optimize_out(void)
1279+void optimize_out_test(void)
14991280 {
15001281 int i = 0 ? undefined_function() : defined_function();
15011282 printf ("oo:%d\n", i);
@@ -1636,8 +1417,6 @@ void compound_literal_test(void) · 134 unmodified lines
16361417 int *p, i;
16371418 char *q, *q3;
16381419
1639− printf("compound_test:\n");
1640−
16411420 p = (int []){1, 2, 3};
16421421 for(i=0;i<3;i++)
16431422 printf(" %d", p[i]);
@@ -1689,7 +1468,6 @@ int kr_func2(a, b) · 45 unmodified lines
16891468
16901469 kr_test()
16911470 {
1692− printf("kr_test:\n");
16931471 printf("func1=%d\n", kr_func1(3, 4));
16941472 printf("func2=%d\n", kr_func2(3, 4));
16951473 return 0;
@@ -1745,8 +1523,6 @@ void struct_assign_test(void) · 49 unmodified lines
17451523 ps = &s;
17461524 ps->i = 4;
17471525 #if 0
1748− printf("struct_assign_test:\n");
1749−
17501526 s.lsta1.f1 = 1;
17511527 s.lsta1.f2 = 2;
17521528 printf("%d %d\n", s.lsta1.f1, s.lsta1.f2);
@@ -1792,7 +1568,6 @@ void cast_test() · 39 unmodified lines
17921568 unsigned long ul = 0x80000000UL;
17931569 p -= 0x700000000042;
17941570
1795− printf("cast_test:\n");
17961571 a = 0xfffff;
17971572 cast1(a, a, a, a);
17981573 a = 0xffffe;
@@ -1833,7 +1608,7 @@ void cast_test() · 34 unmodified lines
18331608 printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a'));
18341609 printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a'));
18351610
1836−#if CC_NAME != CC_clang /* doesn't like non-portable conversions */
1611+#if CC_NAME != CC_clang /* clang doesn't support non-portable conversions */
18371612 /* from pointer to integer types */
18381613 printf("%d %d %ld %ld %lld %lld\n",
18391614 (int)p, (unsigned int)p,
@@ -1972,8 +1747,6 @@ void init_test(void) · 132 unmodified lines
19721747 /* Addresses on non-weak symbols are non-zero, but not the access itself */
19731748 int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 };
19741749
1975− printf("init_test:\n");
1976−
19771750 printf("sinit1=%d\n", sinit1);
19781751 printf("sinit2=%d\n", sinit2);
19791752 printf("sinit3=%d %d %d %d\n",
@@ -2194,7 +1967,6 @@ void c99_bool_test(void) · 214 unmodified lines
21941967 int a;
21951968 _Bool b, b2;
21961969
2197− printf("bool_test:\n");
21981970 printf("sizeof(_Bool) = %d\n", sizeof(_Bool));
21991971 a = 3;
22001972 printf("cast: %d %d %d\n", (_Bool)10, (_Bool)0, (_Bool)a);
@@ -2222,7 +1994,6 @@ void bitfield_test(void) · 21 unmodified lines
22221994 int f4 : 7;
22231995 unsigned int f5 : 7;
22241996 } st1;
2225− printf("bitfield_test:");
22261997 printf("sizeof(st1) = %d\n", sizeof(st1));
22271998
22281999 st1.f1 = 3;
@@ -2442,7 +2213,6 @@ void float_test(void) · 213 unmodified lines
24422213 static double inf1 = 1.0/0.0;
24432214 static double inf2 = 1e5000;
24442215
2445− printf("float_test:\n");
24462216 printf("sizeof(float) = %d\n", sizeof(float));
24472217 printf("sizeof(double) = %d\n", sizeof(double));
24482218 printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE));
@@ -2490,7 +2260,6 @@ void funcptr_test() · 41 unmodified lines
24902260 } st1;
24912261 long diff;
24922262
2493− printf("funcptr:\n");
24942263 func = &num;
24952264 (*func)(12345);
24962265 func = num;
@@ -2648,7 +2417,6 @@ void longlong_test(void) · 151 unmodified lines
26482417 long long a, b, c;
26492418 int ia;
26502419 unsigned int ua;
2651− printf("longlong_test:\n");
26522420 printf("sizeof(long long) = %d\n", sizeof(long long));
26532421 ia = -1;
26542422 ua = -2;
@@ -2728,7 +2496,6 @@ void longlong_test(void) · 73 unmodified lines
27282496 void manyarg_test(void)
27292497 {
27302498 LONG_DOUBLE ld = 1234567891234LL;
2731− printf("manyarg_test:\n");
27322499 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
27332500 1, 2, 3, 4, 5, 6, 7, 8,
27342501 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
@@ -2912,38 +2679,6 @@ void stdarg_test(void) · 177 unmodified lines
29122679 stdarg_syntax(1, 17);
29132680 }
29142681
2915−void whitespace_test(void)
2916−{
2917− char *str;
2918−
2919− #if 1
2920− pri\
2921−ntf("whitspace:\n");
2922−#endif
2923− pf("N=%d\n", 2);
2924−
2925−#ifdef CORRECT_CR_HANDLING
2926− pri\
2927−ntf("aaa=%d\n", 3);
2928−#endif
2929−
2930− pri\
2931−\
2932−ntf("min=%d\n", 4);
2933−
2934−#ifdef ACCEPT_CR_IN_STRINGS
2935− printf("len1=%d\n", strlen("
2936−"));
2937−#ifdef CORRECT_CR_HANDLING
2938− str = "
2939−";
2940− printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
2941−#endif
2942− printf("len1=%d\n", strlen(" a
2943−"));
2944−#endif /* ACCEPT_CR_IN_STRINGS */
2945−}
2946−
29472682 int reltab[3] = { 1, 2, 3 };
29482683
29492684 int *rel1 = &reltab[1];
@@ -3000,7 +2735,7 @@ int cmpfn(); · 50 unmodified lines
30002735 printf("cmpfn=%lx\n", (long)cmpfn);
30012736 }
30022737
3003−void old_style_function(void)
2738+void old_style_function_test(void)
30042739 {
30052740 old_style_f((void *)1, 2, 3.0);
30062741 decl_func1(NULL);
@@ -3027,7 +2762,7 @@ void *bounds_checking_is_enabled() · 20 unmodified lines
30272762
30282763 typedef int constant_negative_array_size_as_compile_time_assertion_idiom[(1 ? 2 : 0) - 1];
30292764
3030−void c99_vla_test(int size1, int size2)
2765+void c99_vla_test_1(int size1, int size2)
30312766 {
30322767 #if defined __i386__ || defined __x86_64__
30332768 int size = size1 * size2;
@@ -3078,6 +2813,12 @@ void c99_vla_test(int size1, int size2) · 44 unmodified lines
30782813 #endif
30792814 }
30802815
2816+void c99_vla_test(void)
2817+{
2818+ c99_vla_test_1(5, 2);
2819+}
2820+
2821+
30812822 void sizeof_test(void)
30822823 {
30832824 int a;
@@ -3750,8 +3491,6 @@ void asm_test(void) · 666 unmodified lines
37503491 #endif
37513492 register int regvar asm("%esi");
37523493
3753− printf("inline asm:\n");
3754−
37553494 // parse 0x1E-1 as 3 tokens in asm mode
37563495 asm volatile ("mov $0x1E-1,%eax");
37573496
@@ -3902,7 +3641,9 @@ void builtin_test(void) · 144 unmodified lines
39023641 //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));
39033642 }
39043643
3905−#ifndef _WIN32
3644+#ifdef _WIN32
3645+void weak_test(void) {}
3646+#else
39063647 extern int __attribute__((weak)) weak_f1(void);
39073648 extern int __attribute__((weak)) weak_f2(void);
39083649 extern int weak_f3(void);
@@ -4170,6 +3911,14 @@ char via_volatile (char i) · 261 unmodified lines
41703911 return vi;
41713912 }
41723913
3914+void volatile_test(void)
3915+{
3916+ if (via_volatile (42) != 42)
3917+ printf (" broken\n");
3918+ else
3919+ printf (" ok\n");
3920+}
3921+
41733922 struct __attribute__((__packed__)) Spacked {
41743923 char a;
41753924 short b;
@@ -4250,3 +3999,122 @@ void bounds_check1_test (void) · 74 unmodified lines
42503999 pv(x);
42514000 pv(y);
42524001 }
4002+
4003+/* gcc 2.95.3 does not handle correctly CR in strings or after strays */
4004+#define CORRECT_CR_HANDLING
4005+
4006+/* deprecated and no longer supported in gcc 3.3 */
4007+#ifdef __TINYC__
4008+# define ACCEPT_CR_IN_STRINGS
4009+#endif
4010+
4011+/* keep this as the last test because GCC messes up line-numbers
4012+ with the ^L^K^M characters below */
4013+void whitespace_test(void)
4014+{
4015+ char *str;
4016+
4017+ #if 1
4018+ pri\
4019+ntf("whitspace:\n");
4020+#endif
4021+ pf("N=%d\n", 2);
4022+
4023+#ifdef CORRECT_CR_HANDLING
4024+ pri\
4025+ntf("aaa=%d\n", 3);
4026+#endif
4027+
4028+ pri\
4029+\
4030+ntf("min=%d\n", 4);
4031+
4032+#ifdef ACCEPT_CR_IN_STRINGS
4033+ printf("len1=%d\n", strlen("
4034+"));
4035+#ifdef CORRECT_CR_HANDLING
4036+ str = "
4037+";
4038+ printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
4039+#endif
4040+ printf("len1=%d\n", strlen(" a
4041+"));
4042+#else
4043+ printf("len1=1\nlen1=1 str[0]=10\nlen1=3\n");
4044+#endif /* ACCEPT_CR_IN_STRINGS */
4045+
4046+#ifdef __LINE__
4047+ printf("__LINE__ defined\n");
4048+#endif
4049+
4050+#if 0
4051+ /* wrong with GCC */
4052+ printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__);
4053+#line 1111
4054+ printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__);
4055+#line 2222 "test"
4056+ printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__);
4057+#endif
4058+}
4059+
4060+#define RUN(test) puts("---- " #test " ----"), test(), puts("")
4061+
4062+int main(int argc, char **argv)
4063+{
4064+ RUN(whitespace_test);
4065+ RUN(macro_test);
4066+ RUN(recursive_macro_test);
4067+ RUN(string_test);
4068+ RUN(expr_test);
4069+ RUN(scope_test);
4070+ RUN(scope2_test);
4071+ RUN(forward_test);
4072+ RUN(funcptr_test);
4073+ RUN(if_test);
4074+ RUN(loop_test);
4075+ RUN(switch_test);
4076+ RUN(goto_test);
4077+ RUN(enum_test);
4078+ RUN(typedef_test);
4079+ RUN(struct_test);
4080+ RUN(array_test);
4081+ RUN(expr_ptr_test);
4082+ RUN(bool_test);
4083+ RUN(optimize_out_test);
4084+ RUN(expr2_test);
4085+ RUN(constant_expr_test);
4086+ RUN(expr_cmp_test);
4087+ RUN(char_short_test);
4088+ RUN(init_test);
4089+ RUN(compound_literal_test);
4090+ RUN(kr_test);
4091+ RUN(struct_assign_test);
4092+ RUN(cast_test);
4093+ RUN(bitfield_test);
4094+ RUN(c99_bool_test);
4095+ RUN(float_test);
4096+ RUN(longlong_test);
4097+ RUN(manyarg_test);
4098+ RUN(stdarg_test);
4099+ RUN(relocation_test);
4100+ RUN(old_style_function_test);
4101+ RUN(alloca_test);
4102+ RUN(c99_vla_test);
4103+ RUN(sizeof_test);
4104+ RUN(typeof_test);
4105+ RUN(statement_expr_test);
4106+ RUN(local_label_test);
4107+ RUN(asm_test);
4108+ RUN(builtin_test);
4109+ RUN(weak_test);
4110+ RUN(global_data_test);
4111+ RUN(cmp_comparison_test);
4112+ RUN(math_cmp_test);
4113+ RUN(callsave_test);
4114+ RUN(builtin_frame_address_test);
4115+ RUN(volatile_test);
4116+ RUN(attrib_test);
4117+ RUN(bounds_check1_test);
4118+
4119+ return 0;
4120+}
tests/tests2/61_integers.c+70−0
@@ -0,0 +1,70 @@
1+#include <stdio.h>
2+
3+/* This was first introduced to test the ARM port */
4+
5+#define UINT_MAX ((unsigned) -1)
6+
7+int main()
8+{
9+ printf("18/21=%u\n", 18/21);
10+ printf("18%%21=%u\n", 18%21);
11+ printf("41/21=%u\n", 41/21);
12+ printf("41%%21=%u\n", 41%21);
13+ printf("42/21=%u\n", 42/21);
14+ printf("42%%21=%u\n", 42%21);
15+ printf("43/21=%u\n", 43/21);
16+ printf("43%%21=%u\n", 43%21);
17+ printf("126/21=%u\n", 126/21);
18+ printf("126%%21=%u\n", 126%21);
19+ printf("131/21=%u\n", 131/21);
20+ printf("131%%21=%u\n", 131%21);
21+ printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2);
22+ printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2);
23+
24+ printf("18/-21=%u\n", 18/-21);
25+ printf("18%%-21=%u\n", 18%-21);
26+ printf("41/-21=%u\n", 41/-21);
27+ printf("41%%-21=%u\n", 41%-21);
28+ printf("42/-21=%u\n", 42/-21);
29+ printf("42%%-21=%u\n", 42%-21);
30+ printf("43/-21=%u\n", 43/-21);
31+ printf("43%%-21=%u\n", 43%-21);
32+ printf("126/-21=%u\n", 126/-21);
33+ printf("126%%-21=%u\n", 126%-21);
34+ printf("131/-21=%u\n", 131/-21);
35+ printf("131%%-21=%u\n", 131%-21);
36+ printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2);
37+ printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2);
38+
39+ printf("-18/21=%u\n", -18/21);
40+ printf("-18%%21=%u\n", -18%21);
41+ printf("-41/21=%u\n", -41/21);
42+ printf("-41%%21=%u\n", -41%21);
43+ printf("-42/21=%u\n", -42/21);
44+ printf("-42%%21=%u\n", -42%21);
45+ printf("-43/21=%u\n", -43/21);
46+ printf("-43%%21=%u\n", -43%21);
47+ printf("-126/21=%u\n", -126/21);
48+ printf("-126%%21=%u\n", -126%21);
49+ printf("-131/21=%u\n", -131/21);
50+ printf("-131%%21=%u\n", -131%21);
51+ printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2);
52+ printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2);
53+
54+ printf("-18/-21=%u\n", -18/-21);
55+ printf("-18%%-21=%u\n", -18%-21);
56+ printf("-41/-21=%u\n", -41/-21);
57+ printf("-41%%-21=%u\n", -41%-21);
58+ printf("-42/-21=%u\n", -42/-21);
59+ printf("-42%%-21=%u\n", -42%-21);
60+ printf("-43/-21=%u\n", -43/-21);
61+ printf("-43%%-21=%u\n", -43%-21);
62+ printf("-126/-21=%u\n", -126/-21);
63+ printf("-126%%-21=%u\n", -126%-21);
64+ printf("-131/-21=%u\n", -131/-21);
65+ printf("-131%%-21=%u\n", -131%-21);
66+ printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2);
67+ printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2);
68+
69+ return 0;
70+}
tests/tests2/61_integers.expect+56−0
@@ -0,0 +1,56 @@
1+18/21=0
2+18%21=18
3+41/21=1
4+41%21=20
5+42/21=2
6+42%21=0
7+43/21=2
8+43%21=1
9+126/21=6
10+126%21=0
11+131/21=6
12+131%21=5
13+(UINT_MAX/2+3)/2=1073741825
14+(UINT_MAX/2+3)%2=0
15+18/-21=0
16+18%-21=18
17+41/-21=4294967295
18+41%-21=20
19+42/-21=4294967294
20+42%-21=0
21+43/-21=4294967294
22+43%-21=1
23+126/-21=4294967290
24+126%-21=0
25+131/-21=4294967290
26+131%-21=5
27+(UINT_MAX/2+3)/-2=0
28+(UINT_MAX/2+3)%-2=2147483650
29+-18/21=0
30+-18%21=4294967278
31+-41/21=4294967295
32+-41%21=4294967276
33+-42/21=4294967294
34+-42%21=0
35+-43/21=4294967294
36+-43%21=4294967295
37+-126/21=4294967290
38+-126%21=0
39+-131/21=4294967290
40+-131%21=4294967291
41+-(UINT_MAX/2+3)/2=1073741823
42+-(UINT_MAX/2+3)%2=0
43+-18/-21=0
44+-18%-21=4294967278
45+-41/-21=1
46+-41%-21=4294967276
47+-42/-21=2
48+-42%-21=0
49+-43/-21=2
50+-43%-21=4294967295
51+-126/-21=6
52+-126%-21=0
53+-131/-21=6
54+-131%-21=4294967291
55+-(UINT_MAX/2+3)/-2=0
56+-(UINT_MAX/2+3)%-2=2147483646
x86_64-gen.c+1−13
@@ -149,7 +149,7 @@ static int func_ret_sub; · 148 unmodified lines
149149 #if defined(CONFIG_TCC_BCHECK)
150150 static addr_t func_bound_offset;
151151 static unsigned long func_bound_ind;
152−static int func_bound_add_epilog;
152+ST_DATA int func_bound_add_epilog;
153153 #endif
154154
155155 #ifdef TCC_TARGET_PE
@@ -639,18 +639,6 @@ static void gcall_or_jmp(int is_jmp) · 483 unmodified lines
639639 greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4));
640640 #endif
641641 oad(0xe8 + is_jmp, 0); /* call/jmp im */
642−#ifdef CONFIG_TCC_BCHECK
643− if (tcc_state->do_bounds_check &&
644− (vtop->sym->v == TOK_alloca ||
645− vtop->sym->v == TOK_setjmp ||
646− vtop->sym->v == TOK__setjmp
647−#ifndef TCC_TARGET_PE
648− || vtop->sym->v == TOK_sigsetjmp
649− || vtop->sym->v == TOK___sigsetjmp
650−#endif
651− ))
652− func_bound_add_epilog = 1;
653−#endif
654642 } else {
655643 /* otherwise, indirect call */
656644 r = TREG_R11;

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