History

tcc -dt -run ... : simpler is better

* -dt now with lowercase t * test snippets now separated by real preprocessor statements which is valid C also for other compilers #if defined test_xxx < test snippet x > #elif defined test_yyy < test snippet y > #elif ... #endif * simpler implementation, behaves like -run if no 'test_...' macros are seen, works with -E too * for demonstration I combined some of the small tests for errors and warnings (56..63,74) in "60_errors_and_warnings.c"

grischka committed 9 years ago

Commit 0cc24d01 parent ba2b25e31 files · +323 −446Browse files

Unified · Split

31 files
  1. libtcc.c +50 −67
  2. tcc.c +25 −15
  3. tcc.h +9 −22
  4. tccasm.c +9 −29
  5. tccgen.c +44 −48
  6. tccpp.c +64 −72
  7. tccrun.c +2 −0
  8. tcctools.c +0 −107
  9. tests/tests2/56_btype_excess-1.c +0 −1
  10. tests/tests2/56_btype_excess-1.expect +0 −1
  11. tests/tests2/57_btype_excess-2.c +0 −1
  12. tests/tests2/57_btype_excess-2.expect +0 −1
  13. tests/tests2/58_function_redefinition.c +0 −9
  14. tests/tests2/58_function_redefinition.expect +0 −1
  15. tests/tests2/59_function_array.c +0 −1
  16. tests/tests2/59_function_array.expect +0 −1
  17. tests/tests2/60_enum_redefinition.c +0 −4
  18. tests/tests2/60_enum_redefinition.expect +0 −1
  19. tests/tests2/60_errors_and_warnings.c +51 −0
  20. tests/tests2/60_errors_and_warnings.expect +28 −0
  21. tests/tests2/61_undefined_enum.c +0 −1
  22. tests/tests2/61_undefined_enum.expect +0 −1
  23. tests/tests2/62_enumerator_redefinition.c +0 −4
  24. tests/tests2/62_enumerator_redefinition.expect +0 −1
  25. tests/tests2/63_local_enumerator_redefinition.c +0 −14
  26. tests/tests2/63_local_enumerator_redefinition.expect +0 −0
  27. tests/tests2/74_nocode_wanted.c +0 −1
  28. tests/tests2/74_nocode_wanted.expect +0 −1
  29. tests/tests2/96_nodata_wanted.c +23 −23
  30. tests/tests2/96_nodata_wanted.expect +12 −14
  31. tests/tests2/Makefile +6 −5
libtcc.c+50−67
@@ -508,8 +508,9 @@ static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) · 507 unmodified lines
508508
509509 if (!s1->error_func) {
510510 /* default case: stderr */
511− if (s1->ppfp) /* print a newline during tcc -E */
512− fprintf(s1->ppfp, "\n"), fflush(s1->ppfp);
511+ if (s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout)
512+ /* print a newline during tcc -E */
513+ printf("\n"), fflush(stdout);
513514 fflush(stdout); /* flush -v output */
514515 fprintf(stderr, "%s\n", buf);
515516 fflush(stderr); /* print error/warning now (win32) */
@@ -587,6 +588,7 @@ ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen) · 71 unmodified lines
587588 bf->fd = -1;
588589 bf->prev = file;
589590 file = bf;
591+ tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
590592 }
591593
592594 ST_FUNC void tcc_close(void)
@@ -622,36 +624,36 @@ ST_FUNC int tcc_open(TCCState *s1, const char *filename) · 29 unmodified lines
622624 return fd;
623625 }
624626
625−/* compile the C file opened in 'file'. Return non zero if errors. */
627+/* compile the file opened in 'file'. Return non zero if errors. */
626628 static int tcc_compile(TCCState *s1)
627629 {
628630 Sym *define_start;
631+ int filetype, is_asm;
629632
630633 define_start = define_stack;
634+ filetype = s1->filetype;
635+ is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP;
636+
631637 if (setjmp(s1->error_jmp_buf) == 0) {
632638 s1->nb_errors = 0;
633639 s1->error_set_jmp_enabled = 1;
634640
635− preprocess_start(s1);
636− tccgen_start(s1);
637−#ifdef INC_DEBUG
638− printf("%s: **** new file\n", file->filename);
641+ preprocess_start(s1, is_asm);
642+ if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
643+ tcc_preprocess(s1);
644+ } else if (is_asm) {
645+#ifdef CONFIG_TCC_ASM
646+ tcc_assemble(s1, filetype == AFF_TYPE_ASMPP);
647+#else
648+ tcc_error_noabort("asm not supported");
639649 #endif
640− ch = file->buf_ptr[0];
641− tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
642− parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
643− next();
644− decl(VT_CONST);
645− if (tok != TOK_EOF)
646− expect("declaration");
647− /* free defines here already on behalf of of M.M.'s possibly existing
648− experimental preprocessor implementation. The normal call below
649− is still there to free after error-longjmp */
650− free_defines(define_start);
651− tccgen_end(s1);
650+ } else {
651+ tccgen_compile(s1);
652+ }
652653 }
653654 s1->error_set_jmp_enabled = 0;
654655
656+ preprocess_end(s1);
655657 free_inline_functions(s1);
656658 /* reset define stack, but keep -D and built-ins */
657659 free_defines(define_start);
@@ -689,10 +691,8 @@ LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *valu · 31 unmodified lines
689691 memcpy(file->buffer + len1 + 1, value, len2);
690692
691693 /* parse with define parser */
692− ch = file->buf_ptr[0];
693694 next_nomacro();
694695 parse_define();
695−
696696 tcc_close();
697697 }
698698
@@ -713,6 +713,8 @@ static void tcc_cleanup(void) · 14 unmodified lines
713713 {
714714 if (NULL == tcc_state)
715715 return;
716+ while (file)
717+ tcc_close();
716718 tccpp_delete(tcc_state);
717719 tcc_state = NULL;
718720 /* free sym_pools */
@@ -993,26 +995,7 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) · 274 unmodified lines
993995
994996 ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
995997 {
996− int ret, filetype;
997−
998− filetype = flags & 0x0F;
999− if (filetype == 0) {
1000− /* use a file extension to detect a filetype */
1001− const char *ext = tcc_fileextension(filename);
1002− if (ext[0]) {
1003− ext++;
1004− if (!strcmp(ext, "S"))
1005− filetype = AFF_TYPE_ASMPP;
1006− else if (!strcmp(ext, "s"))
1007− filetype = AFF_TYPE_ASM;
1008− else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i"))
1009− filetype = AFF_TYPE_C;
1010− else
1011− filetype = AFF_TYPE_BIN;
1012− } else {
1013− filetype = AFF_TYPE_C;
1014− }
1015− }
998+ int ret;
1016999
10171000 /* open the file */
10181001 ret = tcc_open(s1, filename);
@@ -1026,26 +1009,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 7 unmodified lines
10261009 dynarray_add(&s1->target_deps, &s1->nb_target_deps,
10271010 tcc_strdup(filename));
10281011
1029− parse_flags = 0;
1030− /* if .S file, define __ASSEMBLER__ like gcc does */
1031− if (filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP) {
1032− tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
1033− parse_flags = PARSE_FLAG_ASM_FILE;
1034− }
1035−
1036− if (flags & AFF_PREPROCESS) {
1037− ret = tcc_preprocess(s1);
1038− } else if (filetype == AFF_TYPE_C) {
1039− ret = tcc_compile(s1);
1040−#ifdef CONFIG_TCC_ASM
1041− } else if (filetype == AFF_TYPE_ASMPP) {
1042− /* non preprocessed assembler */
1043− ret = tcc_assemble(s1, 1);
1044− } else if (filetype == AFF_TYPE_ASM) {
1045− /* preprocessed assembler */
1046− ret = tcc_assemble(s1, 0);
1047−#endif
1048− } else {
1012+ if (flags & AFF_TYPE_BIN) {
10491013 ElfW(Ehdr) ehdr;
10501014 int fd, obj_type;
10511015
@@ -1098,6 +1062,8 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 46 unmodified lines
10981062 tcc_error_noabort("unrecognized file type");
10991063 break;
11001064 }
1065+ } else {
1066+ ret = tcc_compile(s1);
11011067 }
11021068 tcc_close();
11031069 return ret;
@@ -1105,10 +1071,27 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 1 unmodified line
11051071
11061072 LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
11071073 {
1108− if (s->output_type == TCC_OUTPUT_PREPROCESS)
1109− return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS | s->filetype);
1110− else
1111− return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | s->filetype);
1074+ int filetype = s->filetype;
1075+ int flags = AFF_PRINT_ERROR;
1076+ if (filetype == 0) {
1077+ /* use a file extension to detect a filetype */
1078+ const char *ext = tcc_fileextension(filename);
1079+ if (ext[0]) {
1080+ ext++;
1081+ if (!strcmp(ext, "S"))
1082+ filetype = AFF_TYPE_ASMPP;
1083+ else if (!strcmp(ext, "s"))
1084+ filetype = AFF_TYPE_ASM;
1085+ else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i"))
1086+ filetype = AFF_TYPE_C;
1087+ else
1088+ flags |= AFF_TYPE_BIN;
1089+ } else {
1090+ filetype = AFF_TYPE_C;
1091+ }
1092+ s->filetype = filetype;
1093+ }
1094+ return tcc_add_file_internal(s, filename, flags);
11121095 }
11131096
11141097 LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
@@ -1799,8 +1782,8 @@ reparse: · 684 unmodified lines
17991782 s->dflag = 3;
18001783 else if (*optarg == 'M')
18011784 s->dflag = 7;
1802− else if (*optarg == 'T')
1803− s->do_test = argc;
1785+ else if (*optarg == 't')
1786+ s->dflag = 16;
18041787 else if (isnum(*optarg))
18051788 g_debug = atoi(optarg);
18061789 else
tcc.c+25−15
@@ -91,6 +91,7 @@ static const char help2[] = · 90 unmodified lines
9191 " -static link to static libraries (not recommended)\n"
9292 " -dumpversion print version\n"
9393 " -print-search-dirs print search paths\n"
94+ " -dt with -run/-E: auto-define 'test_...' macros\n"
9495 "Ignored options:\n"
9596 " --param -pedantic -pipe -s -std -traditional\n"
9697 "-W... warnings:\n"
@@ -244,18 +245,21 @@ static unsigned getclock_ms(void) · 147 unmodified lines
244245 #endif
245246 }
246247
247−int main(int argc, char **argv)
248+int main(int argc0, char **argv0)
248249 {
249250 TCCState *s;
250− int ret, opt, n = 0;
251+ int ret, opt, n = 0, t = 0;
251252 unsigned start_time = 0;
252253 const char *first_file;
254+ int argc; char **argv;
255+ FILE *ppfp = stdout;
253256
254257 redo:
258+ argc = argc0, argv = argv0;
255259 s = tcc_new();
256260 opt = tcc_parse_args(s, &argc, &argv, 1);
257261
258− if (n == 0) {
262+ if ((n | t) == 0) {
259263 if (opt == OPT_HELP)
260264 return printf(help), 1;
261265 if (opt == OPT_HELP2)
@@ -282,17 +286,11 @@ redo: · 20 unmodified lines
282286 n = s->nb_files;
283287 if (n == 0)
284288 tcc_error("no input files\n");
285−#ifdef TCC_IS_NATIVE
286− if (s->do_test)
287− tcc_tool_test(s, argc, argv); /* maybe never returns */
288−#endif
289289
290290 if (s->output_type == TCC_OUTPUT_PREPROCESS) {
291− if (!s->outfile) {
292− s->ppfp = stdout;
293− } else {
294− s->ppfp = fopen(s->outfile, "w");
295− if (!s->ppfp)
291+ if (s->outfile) {
292+ ppfp = fopen(s->outfile, "w");
293+ if (!ppfp)
296294 tcc_error("could not write '%s'", s->outfile);
297295 }
298296 } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
@@ -313,6 +311,11 @@ redo: · 14 unmodified lines
313311 if (s->output_type == 0)
314312 s->output_type = TCC_OUTPUT_EXE;
315313 tcc_set_output_type(s, s->output_type);
314+ s->ppfp = ppfp;
315+
316+ if ((s->output_type == TCC_OUTPUT_MEMORY
317+ || s->output_type == TCC_OUTPUT_PREPROCESS) && (s->dflag & 16))
318+ s->dflag |= t ? 32 : 0, s->run_test = ++t, n = s->nb_files;
316319
317320 /* compile or add each files or library */
318321 for (first_file = NULL, ret = 0;;) {
@@ -338,8 +341,7 @@ redo: · 19 unmodified lines
338341 }
339342
340343 if (s->output_type == TCC_OUTPUT_PREPROCESS) {
341− if (s->outfile)
342− fclose(s->ppfp);
344+ ;
343345 } else if (0 == ret) {
344346 if (s->output_type == TCC_OUTPUT_MEMORY) {
345347 #ifdef TCC_IS_NATIVE
@@ -355,10 +357,18 @@ redo: · 9 unmodified lines
355357 }
356358 }
357359
358− if (s->do_bench && ret == 0 && n == 0)
360+ if (t)
361+ ret = 0;
362+ if (s->run_test)
363+ t = 0;
364+ if (s->do_bench && (n | t | ret) == 0)
359365 tcc_print_stats(s, getclock_ms() - start_time);
360366 tcc_delete(s);
361367 if (ret == 0 && n)
362368 goto redo; /* compile more files with -c */
369+ if (t)
370+ goto redo; /* run more tests with -dt -run */
371+ if (ppfp && ppfp != stdout)
372+ fclose(ppfp);
363373 return ret;
364374 }
tcc.h+9−22
@@ -556,15 +556,6 @@ typedef struct BufferedFile { · 555 unmodified lines
556556 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
557557 #define CH_EOF (-1) /* end of file */
558558
559−/* parsing state (used to save parser state to reparse part of the
560− source several times) */
561−typedef struct ParseState {
562− const int *macro_ptr;
563− int line_num;
564− int tok;
565− CValue tokc;
566−} ParseState;
567−
568559 /* used to record tokens */
569560 typedef struct TokenString {
570561 int *str;
@@ -572,6 +563,7 @@ typedef struct TokenString { · 1 unmodified line
572563 int lastlen;
573564 int allocated_len;
574565 int last_line_num;
566+ int save_line_num;
575567 /* used to chain token-strings with begin/end_macro() */
576568 struct TokenString *prev;
577569 const int *prev_ptr;
@@ -675,6 +667,7 @@ struct TCCState { · 97 unmodified lines
675667 #ifdef TCC_TARGET_ARM
676668 enum float_abi float_abi; /* float ABI of the generated code*/
677669 #endif
670+ int run_test; /* nth test to run with -dt -run */
678671
679672 addr_t text_addr; /* address of text section */
680673 int has_text_addr;
@@ -813,7 +806,6 @@ struct TCCState { · 132 unmodified lines
813806 int option_pthread; /* -pthread option */
814807 int argc;
815808 char **argv;
816− int do_test;
817809 };
818810
819811 struct filespec {
@@ -1145,14 +1137,13 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 325 unmodified lines
11451137 /* flags: */
11461138 #define AFF_PRINT_ERROR 0x10 /* print error if file not found */
11471139 #define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */
1148−#define AFF_PREPROCESS 0x40 /* preprocess file */
1149−/* combined with: */
1140+#define AFF_TYPE_BIN 0x40 /* file to add is binary */
1141+/* s->filetype: */
11501142 #define AFF_TYPE_NONE 0
11511143 #define AFF_TYPE_C 1
11521144 #define AFF_TYPE_ASM 2
11531145 #define AFF_TYPE_ASMPP 3
1154−#define AFF_TYPE_BIN 4
1155−#define AFF_TYPE_LIB 5
1146+#define AFF_TYPE_LIB 4
11561147 /* values from tcc_object_type(...) */
11571148 #define AFF_BINTYPE_REL 1
11581149 #define AFF_BINTYPE_DYN 2
@@ -1220,9 +1211,7 @@ ST_FUNC TokenSym *tok_alloc(const char *str, int len); · 61 unmodified lines
12201211 ST_FUNC const char *get_tok_str(int v, CValue *cv);
12211212 ST_FUNC void begin_macro(TokenString *str, int alloc);
12221213 ST_FUNC void end_macro(void);
1223−ST_FUNC void set_idnum(int c, int val);
1224−ST_FUNC void save_parse_state(ParseState *s);
1225−ST_FUNC void restore_parse_state(ParseState *s);
1214+ST_FUNC int set_idnum(int c, int val);
12261215 ST_INLN void tok_str_new(TokenString *s);
12271216 ST_FUNC TokenString *tok_str_alloc(void);
12281217 ST_FUNC void tok_str_free(TokenString *s);
@@ -1241,7 +1230,8 @@ ST_FUNC void preprocess(int is_bof); · 12 unmodified lines
12411230 ST_FUNC void next_nomacro(void);
12421231 ST_FUNC void next(void);
12431232 ST_INLN void unget_tok(int last_tok);
1244−ST_FUNC void preprocess_start(TCCState *s1);
1233+ST_FUNC void preprocess_start(TCCState *s1, int is_asm);
1234+ST_FUNC void preprocess_end(TCCState *s1);
12451235 ST_FUNC void tccpp_new(TCCState *s);
12461236 ST_FUNC void tccpp_delete(TCCState *s);
12471237 ST_FUNC int tcc_preprocess(TCCState *s1);
@@ -1298,9 +1288,7 @@ ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym); · 50 unmodified lines
12981288 ST_FUNC void tcc_debug_funcend(TCCState *s1, int size);
12991289 ST_FUNC void tcc_debug_line(TCCState *s1);
13001290
1301−ST_FUNC void tccgen_start(TCCState *s1);
1302−ST_FUNC void tccgen_end(TCCState *s1);
1303−
1291+ST_FUNC int tccgen_compile(TCCState *s1);
13041292 ST_FUNC void free_inline_functions(TCCState *s);
13051293 ST_FUNC void check_vstack(void);
13061294
@@ -1342,7 +1330,6 @@ ST_FUNC void expr_prod(void); · 35 unmodified lines
13421330 ST_FUNC void expr_sum(void);
13431331 ST_FUNC void gexpr(void);
13441332 ST_FUNC int expr_const(void);
1345−ST_FUNC void decl(int l);
13461333 #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
13471334 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
13481335 #endif
tccasm.c+9−29
@@ -628,20 +628,16 @@ static void asm_parse_directive(TCCState *s1, int global) · 627 unmodified lines
628628 {
629629 int repeat;
630630 TokenString *init_str;
631− ParseState saved_parse_state = {0};
632631 next();
633632 repeat = asm_int_expr(s1);
634633 init_str = tok_str_alloc();
635− next();
636− while ((tok != TOK_ASMDIR_endr) && (tok != CH_EOF)) {
634+ while (next(), tok != TOK_ASMDIR_endr) {
635+ if (tok == CH_EOF)
636+ tcc_error("we at end of file, .endr not found");
637637 tok_str_add_tok(init_str);
638− next();
639638 }
640− if (tok == CH_EOF) tcc_error("we at end of file, .endr not found");
641− next();
642639 tok_str_add(init_str, -1);
643640 tok_str_add(init_str, 0);
644− save_parse_state(&saved_parse_state);
645641 begin_macro(init_str, 1);
646642 while (repeat-- > 0) {
647643 tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS),
@@ -649,7 +645,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 1 unmodified line
649645 macro_ptr = init_str->str;
650646 }
651647 end_macro();
652− restore_parse_state(&saved_parse_state);
648+ next();
653649 break;
654650 }
655651 case TOK_ASMDIR_org:
@@ -917,13 +913,10 @@ static void asm_parse_directive(TCCState *s1, int global) · 261 unmodified lines
917913 static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
918914 {
919915 int opcode;
916+ int saved_parse_flags = parse_flags;
920917
921918 /* XXX: undefine C labels */
922−
923− ch = file->buf_ptr[0];
924− tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
925919 parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;
926− set_idnum('.', IS_ID);
927920 if (do_preprocess)
928921 parse_flags |= PARSE_FLAG_PREPROCESS;
929922 for(;;) {
@@ -990,30 +983,22 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) · 60 unmodified lines
990983 }
991984
992985 asm_free_labels(s1);
986+ parse_flags = saved_parse_flags;
993987 return 0;
994988 }
995989
996990 /* Assemble the current file */
997991 ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
998992 {
999− Sym *define_start;
1000993 int ret;
1001−
1002− define_start = define_stack;
1003− preprocess_start(s1);
1004994 tcc_debug_start(s1);
1005−
1006995 /* default section is text */
1007996 cur_text_section = text_section;
1008997 ind = cur_text_section->data_offset;
1009998 nocode_wanted = 0;
1010−
1011999 ret = tcc_assemble_internal(s1, do_preprocess, 1);
1012−
10131000 cur_text_section->data_offset = ind;
1014−
10151001 tcc_debug_end(s1);
1016− free_defines(define_start);
10171002 return ret;
10181003 }
10191004
@@ -1025,21 +1010,16 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) · 5 unmodified lines
10251010 end */
10261011 static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global)
10271012 {
1028− int saved_parse_flags;
1029− const int *saved_macro_ptr;
1030−
1031− saved_parse_flags = parse_flags;
1032− saved_macro_ptr = macro_ptr;
1013+ const int *saved_macro_ptr = macro_ptr;
1014+ int dotid = set_idnum('.', IS_ID);
10331015
10341016 tcc_open_bf(s1, ":asm:", len);
10351017 memcpy(file->buffer, str, len);
1036−
10371018 macro_ptr = NULL;
10381019 tcc_assemble_internal(s1, 0, global);
10391020 tcc_close();
10401021
1041− parse_flags = saved_parse_flags;
1042− set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
1022+ set_idnum('.', dotid);
10431023 macro_ptr = saved_macro_ptr;
10441024 }
10451025
tccgen.c+44−48
@@ -84,6 +84,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c); · 83 unmodified lines
8484 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
8585 static void block(int *bsym, int *csym, int is_expr);
8686 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
87+static void decl(int l);
8788 static int decl0(int l, int is_for_loop_init, Sym *);
8889 static void expr_eq(void);
8990 static void vla_runtime_type_size(CType *type, int *a);
@@ -91,9 +92,9 @@ static void vla_sp_restore(void); · 1 unmodified line
9192 static void vla_sp_restore_root(void);
9293 static int is_compatible_unqualified_types(CType *type1, CType *type2);
9394 static inline int64_t expr_const64(void);
94−ST_FUNC void vpush64(int ty, unsigned long long v);
95−ST_FUNC void vpush(CType *type);
96−ST_FUNC int gvtst(int inv, int t);
95+static void vpush64(int ty, unsigned long long v);
96+static void vpush(CType *type);
97+static int gvtst(int inv, int t);
9798 static void gen_inline_functions(TCCState *s);
9899 static void skip_or_save_block(TokenString **str);
99100 static void gv_dup(void);
@@ -225,7 +226,7 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size) · 125 unmodified lines
225226 }
226227
227228 /* ------------------------------------------------------------------------- */
228−ST_FUNC void tccgen_start(TCCState *s1)
229+ST_FUNC int tccgen_compile(TCCState *s1)
229230 {
230231 cur_text_section = NULL;
231232 funcname = "";
@@ -253,14 +254,22 @@ ST_FUNC void tccgen_start(TCCState *s1) · 21 unmodified lines
253254 #ifdef TCC_TARGET_ARM
254255 arm_init(s1);
255256 #endif
256−}
257257
258−ST_FUNC void tccgen_end(TCCState *s1)
259−{
258+#ifdef INC_DEBUG
259+ printf("%s: **** new file\n", file->filename);
260+#endif
261+
262+ parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
263+ next();
264+ decl(VT_CONST);
265+ if (tok != TOK_EOF)
266+ expect("declaration");
267+
260268 gen_inline_functions(s1);
261269 check_vstack();
262270 /* end of translation unit info */
263271 tcc_debug_end(s1);
272+ return 0;
264273 }
265274
266275 /* ------------------------------------------------------------------------- */
@@ -4441,15 +4450,11 @@ static void gfunc_param_typed(Sym *func, Sym *arg) · 4174 unmodified lines
44414450 }
44424451 }
44434452
4444−/* parse an expression and return its type without any side effect.
4445− If UNRY we parse an unary expression, otherwise a full one. */
4446−static void expr_type(CType *type, int unry)
4453+/* parse an expression and return its type without any side effect. */
4454+static void expr_type(CType *type, void (*expr_fn)(void))
44474455 {
44484456 nocode_wanted++;
4449− if (unry)
4450− unary();
4451− else
4452− gexpr();
4457+ expr_fn();
44534458 *type = vtop->type;
44544459 vpop();
44554460 nocode_wanted--;
@@ -4466,7 +4471,7 @@ static void parse_expr_type(CType *type) · 10 unmodified lines
44664471 if (parse_btype(type, &ad)) {
44674472 type_decl(type, &ad, &n, TYPE_ABSTRACT);
44684473 } else {
4469− expr_type(type, 0);
4474+ expr_type(type, gexpr);
44704475 }
44714476 skip(')');
44724477 }
@@ -4694,7 +4699,7 @@ ST_FUNC void unary(void) · 221 unmodified lines
46944699 t = tok;
46954700 next();
46964701 in_sizeof++;
4697− expr_type(&type, 1); // Perform a in_sizeof = 0;
4702+ expr_type(&type, unary); /* Perform a in_sizeof = 0; */
46984703 s = vtop[1].sym; /* hack: accessing previous vtop */
46994704 size = type_size(&type, &align);
47004705 if (s && s->a.aligned)
@@ -4896,70 +4901,60 @@ ST_FUNC void unary(void) · 195 unmodified lines
48964901 CType controlling_type;
48974902 int has_default = 0;
48984903 int has_match = 0;
4899− CType cur_type;
4900− AttributeDef ad_tmp;
49014904 int learn = 0;
49024905 TokenString *str = NULL;
4903− ParseState saved_parse_state;
49044906
49054907 next();
49064908 skip('(');
4907− expr_type(&controlling_type, 1);
4908− if (controlling_type.t & VT_ARRAY)
4909− controlling_type.t = VT_PTR;
4910− controlling_type.t &= ~VT_CONSTANT;
4911− controlling_type.t &= ~VT_VOLATILE;
4909+ expr_type(&controlling_type, expr_eq);
4910+ controlling_type.t &= ~(VT_CONSTANT|VT_VOLATILE|VT_ARRAY);
49124911 for (;;) {
49134912 learn = 0;
49144913 skip(',');
49154914 if (tok == TOK_DEFAULT) {
49164915 if (has_default)
49174916 tcc_error("too many 'default'");
4918− if (!has_match) {
4919− has_default = 1;
4917+ has_default = 1;
4918+ if (!has_match)
49204919 learn = 1;
4921− }
49224920 next();
49234921 } else {
4922+ AttributeDef ad_tmp;
49244923 int itmp;
4925−
4924+ CType cur_type;
49264925 parse_btype(&cur_type, &ad_tmp);
49274926 type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
49284927 if (compare_types(&controlling_type, &cur_type, 0)) {
49294928 if (has_match) {
49304929 // tcc_error("type match twice");
49314930 }
4932− if (str)
4933− tok_str_free(str);
49344931 has_match = 1;
49354932 learn = 1;
49364933 }
49374934 }
49384935 skip(':');
49394936 if (learn) {
4937+ if (str)
4938+ tok_str_free(str);
49404939 skip_or_save_block(&str);
49414940 } else {
49424941 skip_or_save_block(NULL);
49434942 }
4944− if (tok == ',')
4945− continue;
4946− else if (tok == ')')
4943+ if (tok == ')')
49474944 break;
49484945 }
4949− if (!has_match && !has_default) {
4950− char buf[256];
4951−
4952− type_to_str(buf, 256, &controlling_type, NULL);
4953− tcc_error("_Generic selector of type '%s' is not compatible with any assosiation",
4954− buf);
4946+ if (!str) {
4947+ char buf[60];
4948+ type_to_str(buf, sizeof buf, &controlling_type, NULL);
4949+ tcc_error("type '%s' does not match any association", buf);
49554950 }
4956− skip(')');
4957− save_parse_state(&saved_parse_state);
49584951 begin_macro(str, 1);
49594952 next();
49604953 expr_eq();
4954+ if (tok != TOK_EOF)
4955+ expect(",");
49614956 end_macro();
4962− restore_parse_state(&saved_parse_state);
4957+ next();
49634958 break;
49644959 }
49654960 // special qnan , snan and infinity values
@@ -5599,7 +5594,9 @@ ST_FUNC void gexpr(void) · 633 unmodified lines
55995594 static void expr_const1(void)
56005595 {
56015596 const_wanted++;
5597+ nocode_wanted++;
56025598 expr_cond();
5599+ nocode_wanted--;
56035600 const_wanted--;
56045601 }
56055602
@@ -6721,8 +6718,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 1115 unmodified lines
67216718 int has_init, int v, int scope)
67226719 {
67236720 int size, align, addr;
6724− ParseState saved_parse_state = {0};
67256721 TokenString *init_str = NULL;
6722+
67266723 Section *sec;
67276724 Sym *flexible_array;
67286725 Sym *sym = NULL;
@@ -6768,10 +6765,9 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 39 unmodified lines
67686765 } else {
67696766 skip_or_save_block(&init_str);
67706767 }
6771−
6772− /* compute size */
6773− save_parse_state(&saved_parse_state);
6768+ unget_tok(0);
67746769
6770+ /* compute size */
67756771 begin_macro(init_str, 1);
67766772 next();
67776773 decl_initializer(type, NULL, 0, 1, 1);
@@ -6959,7 +6955,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 181 unmodified lines
69596955 /* restore parse state if needed */
69606956 if (init_str) {
69616957 end_macro();
6962− restore_parse_state(&saved_parse_state);
6958+ next();
69636959 }
69646960
69656961 nocode_wanted = saved_nocode_wanted;
@@ -7328,7 +7324,7 @@ found: · 362 unmodified lines
73287324 return 0;
73297325 }
73307326
7331−ST_FUNC void decl(int l)
7327+static void decl(int l)
73327328 {
73337329 decl0(l, 0, NULL);
73347330 }
tccpp.c+64−72
@@ -820,9 +820,11 @@ ST_FUNC uint8_t *parse_comment(uint8_t *p) · 819 unmodified lines
820820 return p;
821821 }
822822
823−ST_FUNC void set_idnum(int c, int val)
823+ST_FUNC int set_idnum(int c, int val)
824824 {
825+ int prev = isidnum_table[c - CH_EOF];
825826 isidnum_table[c - CH_EOF] = val;
827+ return prev;
826828 }
827829
828830 #define cinp minp
@@ -999,30 +1001,6 @@ _default: · 170 unmodified lines
9991001 file->buf_ptr = p;
10001002 }
10011003
1002−/* ParseState handling */
1003−
1004−/* XXX: currently, no include file info is stored. Thus, we cannot display
1005− accurate messages if the function or data definition spans multiple
1006− files */
1007−
1008−/* save current parse state in 's' */
1009−ST_FUNC void save_parse_state(ParseState *s)
1010−{
1011− s->line_num = file->line_num;
1012− s->macro_ptr = macro_ptr;
1013− s->tok = tok;
1014− s->tokc = tokc;
1015−}
1016−
1017−/* restore parse state from 's' */
1018−ST_FUNC void restore_parse_state(ParseState *s)
1019−{
1020− file->line_num = s->line_num;
1021− macro_ptr = s->macro_ptr;
1022− tok = s->tok;
1023− tokc = s->tokc;
1024−}
1025−
10261004 #if 0
10271005 /* return the number of additional 'ints' necessary to store the
10281006 token */
@@ -1124,6 +1102,7 @@ ST_FUNC void begin_macro(TokenString *str, int alloc) · 95 unmodified lines
11241102 str->alloc = alloc;
11251103 str->prev = macro_stack;
11261104 str->prev_ptr = macro_ptr;
1105+ str->save_line_num = file->line_num;
11271106 macro_ptr = str->str;
11281107 macro_stack = str;
11291108 }
@@ -1133,6 +1112,7 @@ ST_FUNC void end_macro(void) · 3 unmodified lines
11331112 TokenString *str = macro_stack;
11341113 macro_stack = str->prev;
11351114 macro_ptr = str->prev_ptr;
1115+ file->line_num = str->save_line_num;
11361116 if (str->alloc == 2) {
11371117 str->alloc = 3; /* just mark as finished */
11381118 } else {
@@ -1402,6 +1382,21 @@ ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep) · 263 unmodified lines
14021382 *ptop = slast;
14031383 }
14041384
1385+/* fake the nth "#if defined test_..." for tcc -dt -run */
1386+static void maybe_run_test(TCCState *s, int *c)
1387+{
1388+ const char *p;
1389+ if (s->include_stack_ptr != s->include_stack)
1390+ return;
1391+ p = get_tok_str(tok, NULL);
1392+ if (0 != memcmp(p, "test_", 5))
1393+ return;
1394+ if (0 != --s->run_test)
1395+ return;
1396+ fprintf(s->ppfp, "\n[%s]\n" + !(s->dflag & 32), p), fflush(s->ppfp);
1397+ *c = 1;
1398+}
1399+
14051400 /* eval an expression for #if/#elif */
14061401 static int expr_preprocess(void)
14071402 {
@@ -1420,6 +1415,8 @@ static int expr_preprocess(void) · 12 unmodified lines
14201415 if (tok < TOK_IDENT)
14211416 expect("identifier");
14221417 c = define_find(tok) != 0;
1418+ if (tcc_state->run_test)
1419+ maybe_run_test(tcc_state, &c);
14231420 if (t == '(') {
14241421 next_nomacro();
14251422 if (tok != ')')
@@ -1467,7 +1464,7 @@ ST_FUNC void parse_define(void) · 41 unmodified lines
14671464 /* '(' must be just after macro definition for MACRO_FUNC */
14681465 next_nomacro_spc();
14691466 if (tok == '(') {
1470− set_idnum('.', 0);
1467+ int dotid = set_idnum('.', 0);
14711468 next_nomacro();
14721469 ps = &first;
14731470 if (tok != ')') for (;;) {
@@ -1495,6 +1492,7 @@ ST_FUNC void parse_define(void) · 21 unmodified lines
14951492 }
14961493 next_nomacro_spc();
14971494 t = MACRO_FUNC;
1495+ set_idnum('.', dotid);
14981496 }
14991497
15001498 tokstr_buf.len = 0;
@@ -1505,7 +1503,6 @@ ST_FUNC void parse_define(void) · 4 unmodified lines
15051503 ID character in asm mode). But '#' should be retained instead of
15061504 regarded as line comment leader, so still don't set ASM_FILE
15071505 in parse_flags. */
1508− set_idnum('.', (saved_parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
15091506 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
15101507 /* remove spaces around ## and after '#' */
15111508 if (TOK_TWOSHARPS == tok) {
@@ -1613,7 +1610,7 @@ static void pragma_parse(TCCState *s1) · 101 unmodified lines
16131610 } else if (tok == TOK_once) {
16141611 search_cached_include(s1, file->filename, 1)->once = pp_once;
16151612
1616− } else if (s1->ppfp) {
1613+ } else if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
16171614 /* tcc -E: keep pragmas below unchanged */
16181615 unget_tok(' ');
16191616 unget_tok(TOK_PRAGMA);
@@ -3043,6 +3040,7 @@ static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2) · 1423 unmodified lines
30433040
30443041 tcc_open_bf(tcc_state, ":paste:", cstr.size);
30453042 memcpy(file->buffer, cstr.data, cstr.size);
3043+ tok_flags = 0;
30463044 for (;;) {
30473045 next_nomacro1();
30483046 if (0 == *file->buf_ptr)
@@ -3164,6 +3162,8 @@ static int next_argstream(Sym **nested_list, TokenString *ws_str) · 115 unmodified lines
31643162 break;
31653163 ch = ' ';
31663164 }
3165+ if (ch == '\n')
3166+ file->line_num++;
31673167 if (!(ch == '\f' || ch == '\v' || ch == '\r'))
31683168 tok_str_add(ws_str, ch);
31693169 cinp();
@@ -3483,7 +3483,7 @@ ST_INLN void unget_tok(int last_tok) · 313 unmodified lines
34833483 tok = last_tok;
34843484 }
34853485
3486−ST_FUNC void preprocess_start(TCCState *s1)
3486+ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
34873487 {
34883488 char *buf;
34893489
@@ -3496,7 +3496,7 @@ ST_FUNC void preprocess_start(TCCState *s1) · 6 unmodified lines
34963496 s1->pack_stack_ptr = s1->pack_stack;
34973497
34983498 set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0);
3499− set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
3499+ set_idnum('.', is_asm ? IS_ID : 0);
35003500
35013501 buf = tcc_malloc(3 + strlen(file->filename));
35023502 sprintf(buf, "\"%s\"", file->filename);
@@ -3517,6 +3517,20 @@ ST_FUNC void preprocess_start(TCCState *s1) · 14 unmodified lines
35173517 memcpy(file->buffer, cstr.data, cstr.size);
35183518 cstr_free(&cstr);
35193519 }
3520+
3521+ if (is_asm)
3522+ tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
3523+
3524+ parse_flags = is_asm ? PARSE_FLAG_ASM_FILE : 0;
3525+ tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
3526+}
3527+
3528+/* cleanup from error/setjmp */
3529+ST_FUNC void preprocess_end(TCCState *s1)
3530+{
3531+ while (macro_stack)
3532+ end_macro();
3533+ macro_ptr = NULL;
35203534 }
35213535
35223536 ST_FUNC void tccpp_new(TCCState *s)
@@ -3526,6 +3540,7 @@ ST_FUNC void tccpp_new(TCCState *s) · 3 unmodified lines
35263540
35273541 /* might be used in error() before preprocess_start() */
35283542 s->include_stack_ptr = s->include_stack;
3543+ s->ppfp = stdout;
35293544
35303545 /* init isid table */
35313546 for(i = CH_EOF; i<128; i++)
@@ -3570,14 +3585,6 @@ ST_FUNC void tccpp_delete(TCCState *s) · 38 unmodified lines
35703585 /* free -D and compiler defines */
35713586 free_defines(NULL);
35723587
3573− /* cleanup from error/setjmp */
3574− while (macro_stack)
3575− end_macro();
3576− macro_ptr = NULL;
3577−
3578− while (file)
3579− tcc_close();
3580−
35813588 /* free tokens */
35823589 n = tok_ident - TOK_IDENT;
35833590 for(i = 0; i < n; i++)
@@ -3606,19 +3613,16 @@ ST_FUNC void tccpp_delete(TCCState *s) · 22 unmodified lines
36063613 static void tok_print(const char *msg, const int *str)
36073614 {
36083615 FILE *fp;
3609− int t;
3616+ int t, s = 0;
36103617 CValue cval;
36113618
36123619 fp = tcc_state->ppfp;
3613− if (!fp || !tcc_state->dflag)
3614− fp = stdout;
3615−
3616− fprintf(fp, "%s ", msg);
3620+ fprintf(fp, "%s", msg);
36173621 while (str) {
36183622 TOK_GET(&t, &str, &cval);
36193623 if (!t)
36203624 break;
3621− fprintf(fp,"%s", get_tok_str(t, &cval));
3625+ fprintf(fp, " %s" + s, get_tok_str(t, &cval)), s = 1;
36223626 }
36233627 fprintf(fp, "\n");
36243628 }
@@ -3731,20 +3735,14 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 106 unmodified lines
37313735 BufferedFile **iptr;
37323736 int token_seen, spcs, level;
37333737 const char *p;
3734− Sym *define_start;
3738+ char white[400];
37353739
3736− define_start = define_stack;
3737− preprocess_start(s1);
3738−
3739− ch = file->buf_ptr[0];
3740− tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
37413740 parse_flags = PARSE_FLAG_PREPROCESS
37423741 | (parse_flags & PARSE_FLAG_ASM_FILE)
37433742 | PARSE_FLAG_LINEFEED
37443743 | PARSE_FLAG_SPACES
37453744 | PARSE_FLAG_ACCEPT_STRAYS
37463745 ;
3747−
37483746 /* Credits to Fabrice Bellard's initial revision to demonstrate its
37493747 capability to compile and run itself, provided all numbers are
37503748 given as decimals. tcc -E -P10 will do. */
@@ -3754,7 +3752,6 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 3 unmodified lines
37543752 #ifdef PP_BENCH
37553753 /* for PP benchmarks */
37563754 do next(); while (tok != TOK_EOF);
3757− free_defines(define_start);
37583755 return 0;
37593756 #endif
37603757
@@ -3765,48 +3762,43 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 4 unmodified lines
37653762
37663763 token_seen = TOK_LINEFEED, spcs = 0;
37673764 pp_line(s1, file, 0);
3768−
37693765 for (;;) {
37703766 iptr = s1->include_stack_ptr;
37713767 next();
37723768 if (tok == TOK_EOF)
37733769 break;
3770+
37743771 level = s1->include_stack_ptr - iptr;
37753772 if (level) {
37763773 if (level > 0)
37773774 pp_line(s1, *iptr, 0);
37783775 pp_line(s1, file, level);
37793776 }
3780−
3781− if (s1->dflag) {
3777+ if (s1->dflag & 7) {
37823778 pp_debug_defines(s1);
37833779 if (s1->dflag & 4)
37843780 continue;
37853781 }
37863782
3787− if (token_seen == TOK_LINEFEED) {
3788− if (tok == ' ') {
3789− ++spcs;
3790− continue;
3791− }
3792− if (tok == TOK_LINEFEED) {
3793− spcs = 0;
3794− continue;
3795− }
3796− pp_line(s1, file, 0);
3783+ if (is_space(tok)) {
3784+ if (spcs < sizeof white - 1)
3785+ white[spcs++] = tok;
3786+ continue;
37973787 } else if (tok == TOK_LINEFEED) {
3788+ spcs = 0;
3789+ if (token_seen == TOK_LINEFEED)
3790+ continue;
37983791 ++file->line_ref;
3799− } else {
3800− spcs = pp_need_space(token_seen, tok);
3792+ } else if (token_seen == TOK_LINEFEED) {
3793+ pp_line(s1, file, 0);
3794+ } else if (spcs == 0 && pp_need_space(token_seen, tok)) {
3795+ white[spcs++] = ' ';
38013796 }
38023797
3803− while (spcs)
3804− fputs(" ", s1->ppfp), --spcs;
3798+ white[spcs] = 0, fputs(white, s1->ppfp), spcs = 0;
38053799 fputs(p = get_tok_str(tok, &tokc), s1->ppfp);
3806− token_seen = pp_check_he0xE(tok, p);;
3800+ token_seen = pp_check_he0xE(tok, p);
38073801 }
3808− /* reset define stack, but keep -D and built-ins */
3809− free_defines(define_start);
38103802 return 0;
38113803 }
38123804
tccrun.c+2−0
@@ -108,6 +108,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 107 unmodified lines
108108 int (*prog_main)(int, char **);
109109
110110 s1->runtime_main = "main";
111+ if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main))
112+ return 0;
111113 if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
112114 return -1;
113115 prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
tcctools.c+0−107
@@ -543,111 +543,4 @@ ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename) · 542 unmodified lines
543543 fclose(depout);
544544 }
545545
546−#ifdef TCC_IS_NATIVE
547−/* -------------------------------------------------------------- */
548−/* run test snippets from file */
549−
550−static char *readfile(const char *fname)
551−{
552− char *buf;
553− int fsize;
554− FILE *fi;
555− fi = fopen(fname, "rb");
556− if (!fi)
557− return NULL;
558− fseek(fi, 0, SEEK_END);
559− fsize = ftell(fi);
560− fseek(fi, 0, SEEK_SET);
561− buf = tcc_malloc(fsize + 1);
562− fread(buf, fsize, 1, fi);
563− fclose(fi);
564− buf[fsize] = 0;
565− return buf;
566−}
567−
568−static int run_prog(const char *prog, int ac, char **av)
569−{
570− TCCState *s;
571− int (*func)(int, char**);
572− int ret = -10000;
573−
574− s = tcc_new();
575− tcc_parse_args(s, &ac, &av, 1);
576− tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
577− if (tcc_compile_string(s, prog) == -1)
578− goto done;
579− if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0)
580− goto done;
581− func = tcc_get_symbol(s, "main");
582− if (!func)
583− goto done;
584− ret = func(ac, av);
585−done:
586− tcc_delete(s);
587− return ret;
588−}
589−
590−static char *trimback(char *a, char *e)
591−{
592− while (e > a && (unsigned char)e[-1] <= ' ')
593− --e;
594− *e = 0;;
595− return a;
596−}
597−
598−ST_FUNC int tcc_tool_test(TCCState *s, int argc, char **argv)
599−{
600− const char *fname;
601− char *buf, *p, *a, *b, *e, tmp[100];
602− int r = 0, c, n;
603− const char sep[] = "/*-* test";
604−
605− n = s->do_test - argc;
606− if (!n)
607− return 0;
608− fname = argv[0], argv -= n, argc += n;
609−
610− buf = readfile(fname);
611− if (NULL == buf)
612− return -1;
613− p = strstr(buf, sep);
614− if (!p) {
615− tcc_free(buf);
616− return -1;
617− }
618−
619− while (*p) {
620− a = p, p = strchr(p, '\n');
621− if (NULL == p)
622− break;
623− *p++ = 0;
624− b = p, p = strstr(p, sep);
625− if (NULL == p)
626− p = strchr(b, 0);
627− c = *p, *p = 0;
628−
629− trimback(a, b);
630− if (r)
631− printf("\n");
632− printf("%s\n", a);
633− fflush(stdout);
634−
635− e = a += sizeof sep - 5;
636− while (*e && *e != ':')
637− ++e;
638− if (!*e || e - a > 32)
639− e = a + 4;
640− n = snprintf(tmp, sizeof tmp, "#line 1 \"%.*s\"\n", (int)(e - a), a);
641− if (b - buf >= n)
642− b = memcpy(b - n, tmp, n);
643− n = run_prog(b, argc, argv);
644− if (n != -10000)
645− printf("returns %d\n", n);
646− *p = c, ++r;
647− }
648− tcc_free(buf);
649− exit(0);
650−}
651−#endif /* TCC_IS_NATIVE */
652−
653546 /* -------------------------------------------------------------- */
tests/tests2/56_btype_excess-1.c+0−1
@@ -1 +0,0 @@
1−struct A {} int i;
tests/tests2/56_btype_excess-1.expect+0−1
@@ -1 +0,0 @@
1−56_btype_excess-1.c:1: error: too many basic types
tests/tests2/57_btype_excess-2.c+0−1
@@ -1 +0,0 @@
1−char int i;
tests/tests2/57_btype_excess-2.expect+0−1
@@ -1 +0,0 @@
1−57_btype_excess-2.c:1: error: too many basic types
tests/tests2/58_function_redefinition.c+0−9
@@ -1,9 +0,0 @@
1−int f(void)
2−{
3− return 0;
4−}
5−
6−int f(void)
7−{
8− return 1;
9−}
tests/tests2/58_function_redefinition.expect+0−1
@@ -1 +0,0 @@
1−58_function_redefinition.c:7: error: redefinition of 'f'
tests/tests2/59_function_array.c+0−1
@@ -1 +0,0 @@
1−int (*fct)[42](int x);
tests/tests2/59_function_array.expect+0−1
@@ -1 +0,0 @@
1−59_function_array.c:1: error: declaration of an array of functions
tests/tests2/60_enum_redefinition.c+0−4
@@ -1,4 +0,0 @@
1−enum color {RED, GREEN, BLUE};
2−enum color {R, G, B};
3−
4−enum color c;
tests/tests2/60_enum_redefinition.expect+0−1
@@ -1 +0,0 @@
1−60_enum_redefinition.c:2: error: struct/union/enum already defined
tests/tests2/60_errors_and_warnings.c+51−0
@@ -0,0 +1,51 @@
1+#if defined test_56_btype_excess_1
2+struct A {} int i;
3+
4+#elif defined test_57_btype_excess_2
5+char int i;
6+
7+#elif defined test_58_function_redefinition
8+int f(void) { return 0; }
9+int f(void) { return 1; }
10+
11+#elif defined test_global_redefinition
12+int xxx = 1;
13+int xxx;
14+int xxx = 2;
15+
16+#elif defined test_59_function_array
17+int (*fct)[42](int x);
18+
19+#elif defined test_60_enum_redefinition
20+enum color { RED, GREEN, BLUE };
21+enum color { R, G, B };
22+enum color c;
23+
24+#elif defined test_62_enumerator_redefinition
25+enum color { RED, GREEN, BLUE };
26+enum rgb { RED, G, B};
27+enum color c = RED;
28+
29+#elif defined test_63_local_enumerator_redefinition
30+enum {
31+ FOO,
32+ BAR
33+};
34+
35+int main(void)
36+{
37+ enum {
38+ FOO = 2,
39+ BAR
40+ };
41+
42+ return BAR - FOO;
43+}
44+
45+#elif defined test_61_undefined_enum
46+enum rgb3 c = 42;
47+
48+#elif defined test_74_non_const_init
49+int i = i++;
50+
51+#endif
tests/tests2/60_errors_and_warnings.expect+28−0
@@ -0,0 +1,28 @@
1+[test_56_btype_excess_1]
2+60_errors_and_warnings.c:2: error: too many basic types
3+
4+[test_57_btype_excess_2]
5+60_errors_and_warnings.c:5: error: too many basic types
6+
7+[test_58_function_redefinition]
8+60_errors_and_warnings.c:9: error: redefinition of 'f'
9+
10+[test_global_redefinition]
11+60_errors_and_warnings.c:14: error: redefinition of 'xxx'
12+
13+[test_59_function_array]
14+60_errors_and_warnings.c:17: error: declaration of an array of functions
15+
16+[test_60_enum_redefinition]
17+60_errors_and_warnings.c:21: error: struct/union/enum already defined
18+
19+[test_62_enumerator_redefinition]
20+60_errors_and_warnings.c:26: error: redefinition of enumerator 'RED'
21+
22+[test_63_local_enumerator_redefinition]
23+
24+[test_61_undefined_enum]
25+60_errors_and_warnings.c:46: error: unknown type size
26+
27+[test_74_non_const_init]
28+60_errors_and_warnings.c:49: error: initializer element is not constant
tests/tests2/61_undefined_enum.c+0−1
@@ -1 +0,0 @@
1−enum rgb c = 42;
tests/tests2/61_undefined_enum.expect+0−1
@@ -1 +0,0 @@
1−61_undefined_enum.c:1: error: unknown type size
tests/tests2/62_enumerator_redefinition.c+0−4
@@ -1,4 +0,0 @@
1−enum color {RED, GREEN, BLUE};
2−enum rgb {RED, G, B};
3−
4−enum color c = RED;
tests/tests2/62_enumerator_redefinition.expect+0−1
@@ -1 +0,0 @@
1−62_enumerator_redefinition.c:2: error: redefinition of enumerator 'RED'
tests/tests2/63_local_enumerator_redefinition.c+0−14
@@ -1,14 +0,0 @@
1−enum {
2− FOO,
3− BAR
4−};
5−
6−int main(void)
7−{
8− enum {
9− FOO = 2,
10− BAR
11− };
12−
13− return BAR - FOO;
14−}
tests/tests2/63_local_enumerator_redefinition.expect+0−0

Empty file deleted.

tests/tests2/74_nocode_wanted.c+0−1
@@ -1 +0,0 @@
1−int i = i++;
tests/tests2/74_nocode_wanted.expect+0−1
@@ -1 +0,0 @@
1−74_nocode_wanted.c:1: error: initializer element is not constant
tests/tests2/96_nodata_wanted.c+23−23
@@ -1,36 +1,35 @@
11 /*****************************************************************************/
22 /* test 'nodata_wanted' data output suppression */
33
4−/*-* test 1: initializer not computable 1 */
4+#if defined test_static_data_error
55 void foo() {
66 if (1) {
7− static short w = (int)&foo; /* error */
7+ static short w = (int)&foo; /* initializer not computable */
88 }
99 }
1010
11−/*-* test 2: initializer not computable 2 */
11+#elif defined test_static_nodata_error
1212 void foo() {
1313 if (0) {
14− static short w = (int)&foo; /* error */
14+ static short w = (int)&foo; /* initializer not computable */
1515 }
1616 }
1717
18−/*-* test 3: initializer not computable 3 */
18+#elif defined test_global_data_error
1919 void foo();
20−static short w = (int)&foo; /* error */
20+static short w = (int)&foo; /* initializer not computable */
2121
2222
23−/*-* test 4: 2 cast warnings */
23+#elif defined test_local_data_noerror
2424 void foo() {
25− short w = &foo; /* no error */
25+ short w = &foo; /* 2 cast warnings */
2626 }
2727
28−/*-* test 5; nodata_wanted test */
28+#elif defined test_data_suppression
2929 #include <stdio.h>
3030
31−#define DATA_LBL(s) \
32− __asm__(".global d"#s",t"#s"\n.data\nd"#s":\n.text\nt"#s":\n"); \
33− extern char d##s[],t##s[];
31+#define ASMLABELS(s) \
32+ __asm__(".global d"#s",t"#s"\n.data\nd"#s":\n.text\nt"#s":\n")
3433
3534 #define PROG \
3635 static void *p = (void*)&main;\
@@ -47,28 +46,29 @@ void foo() { · 10 unmodified lines
4746
4847 int main()
4948 {
49+ extern char ds1[],ts1[];
50+ extern char ds2[],ts2[];
51+ extern char de1[],te1[];
52+ extern char de2[],te2[];
53+
5054 printf("suppression off\n");
51− DATA_LBL(s1);
5255 if (1) {
56+ ASMLABELS(s1);
5357 PROG
58+ ASMLABELS(e1);
5459 }
55− DATA_LBL(e1);
5660 printf(" data length is %s\n", de1 - ds1 ? "not 0":"0");
57− //printf(" text length is %s\n", te1 - ts1 ? "not 0":"0");
61+ printf(" text length is %s\n", te1 - ts1 ? "not 0":"0");
5862
5963 printf("suppression on\n");
60− DATA_LBL(s2);
6164 if (0) {
65+ ASMLABELS(s2);
6266 PROG
67+ ASMLABELS(e2);
6368 }
64− DATA_LBL(e2);
6569 printf(" data length is %x\n", de2 - ds2);
66− //printf(" text length is %X\n", te2 - ts2);
70+ printf(" text length is %X\n", te2 - ts2);
6771 return 0;
6872 }
6973
70−/*-* test 6: some test */
71−int main()
72−{
73− return 34;
74−}
74+#endif
tests/tests2/96_nodata_wanted.expect+12−14
@@ -1,24 +1,22 @@
1−/*-* test 1: initializer not computable 1 */
2−test 1:3: error: initializer element is not computable at load time
1+[test_static_data_error]
2+96_nodata_wanted.c:7: error: initializer element is not computable at load time
33
4−/*-* test 2: initializer not computable 2 */
5−test 2:3: error: initializer element is not computable at load time
4+[test_static_nodata_error]
5+96_nodata_wanted.c:14: error: initializer element is not computable at load time
66
7−/*-* test 3: initializer not computable 3 */
8−test 3:2: error: initializer element is not computable at load time
7+[test_global_data_error]
8+96_nodata_wanted.c:20: error: initializer element is not computable at load time
99
10−/*-* test 4: 2 cast warnings */
11−test 4:2: warning: assignment makes integer from pointer without a cast
12−test 4:2: warning: nonportable conversion from pointer to char/short
10+[test_local_data_noerror]
11+96_nodata_wanted.c:25: warning: assignment makes integer from pointer without a cast
12+96_nodata_wanted.c:25: warning: nonportable conversion from pointer to char/short
1313
14−/*-* test 5; nodata_wanted test */
14+[test_data_suppression]
1515 suppression off
1616 static data: 8 - 8.0 - 8.0 - main - static string
1717 static bitfields: 333 44 555555 6 7
1818 data length is not 0
19+ text length is not 0
1920 suppression on
2021 data length is 0
21−returns 0
22−
23−/*-* test 6: some test */
24−returns 34
22+ text length is 0
tests/tests2/Makefile+6−5
@@ -20,7 +20,7 @@ endif · 19 unmodified lines
2020 ifeq (,$(filter i386 x86_64,$(ARCH)))
2121 SKIP += 85_asm-outside-function.test
2222 endif
23−ifeq (-$(findstring gcc,$(CC)-)-,--)
23+ifeq (-$(findstring gcc,$(CC))-,--)
2424 SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS))
2525 endif
2626 ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-)
@@ -40,8 +40,9 @@ NORUN = · 13 unmodified lines
4040 FLAGS =
4141 76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers
4242
43−# run the source file cut into snippets
44−96_nodata_wanted.test : FLAGS = -dT
43+# These tests run several snippets from the same file one by one
44+60_errors_and_warnings.test : FLAGS += -dt
45+96_nodata_wanted.test : FLAGS += -dt
4546
4647 # Always generate certain .expects (don't put these in the GIT),
4748 GEN-ALWAYS =
@@ -90,8 +91,8 @@ F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)" · 42 unmodified lines
9091 @$(call GEN,$(SRC)/$*.c) $(FILTER) >$@ 2>&1
9192 @rm -f *.exe *.obj *.pdb
9293
93−# using TCC for .expect if -dT in FLAGS
94−GEN = $(if $(findstring -dT,$(FLAGS)),$(GEN-TCC),$(GEN-CC))
94+# using TCC for .expect if -dt in FLAGS
95+GEN = $(if $(filter -dt,$(FLAGS)),$(GEN-TCC),$(GEN-CC))
9596 GEN-CC = $(CC) -w -std=gnu99 $(FLAGS) $1 -o a.exe && ./a.exe $(ARGS)
9697 GEN-TCC = $(TCC) $(FLAGS) -run $1 $(ARGS)
9798 GEN-MSC = $(MS-CC) $1 && ./$(basename $@).exe

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