From 30df3189b177c65d65094bed3a066a2722fe2dc0 Mon Sep 17 00:00:00 2001 From: grischka Date: Sat, 9 May 2015 14:29:39 +0200 Subject: tccpp: fix issues, add tests * fix some macro expansion issues * add some pp tests in tests/pp * improved tcc -E output for better diff'ability * remove -dD feature (quirky code, exotic feature, didn't work well) Based partially on ideas / researches from PipCet Some issues remain with VA_ARGS macros (if used in a rather tricky way). Also, to keep it simple, the pp doesn't automtically add any extra spaces to separate tokens which otherwise would form wrong tokens if re-read from tcc -E output (such as '+' '=') GCC does that, other compilers don't. * cleanups - #line 01 "file" / # 01 "file" processing - #pragma comment(lib,"foo") - tcc -E: forward some pragmas to output (pack, comment(lib)) - fix macro parameter list parsing mess from a3fc54345949535524d01319e1ca6378b7c2c201 a715d7143d9d17da17e67fec6af1c01409a71a31 (some coffee might help, next time ;) - introduce TOK_PPSTR - to have character constants as written in the file (similar to TOK_PPNUM) - allow '\' appear in macros - new functions begin/end_macro to: - fix switching macro levels during expansion - allow unget_tok to unget more than one tok - slight speedup by using bitflags in isidnum_table Also: - x86_64.c : fix decl after statements - i386-gen,c : fix a vstack leak with VLA on windows - configure/Makefile : build on windows (MSYS) was broken - tcc_warning: fflush stderr to keep output order (win32) --- tccgen.c | 56 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 25 deletions(-) (limited to 'tccgen.c') diff --git a/tccgen.c b/tccgen.c index 5c89b2d..fcec8f1 100644 --- a/tccgen.c +++ b/tccgen.c @@ -59,7 +59,7 @@ ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */ ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */ ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */ -ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop; +ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop; ST_DATA int const_wanted; /* true if constant wanted */ ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */ @@ -68,7 +68,7 @@ ST_DATA CType func_vt; /* current function return type (used by return instructi ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */ ST_DATA int func_vc; ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ -ST_DATA char *funcname; +ST_DATA const char *funcname; ST_DATA CType char_pointer_type, func_old_type, int_type, size_type; @@ -118,6 +118,12 @@ ST_FUNC void test_lvalue(void) expect("lvalue"); } +ST_FUNC void check_vstack(void) +{ + if (pvtop != vtop) + tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop); +} + /* ------------------------------------------------------------------------- */ /* symbol allocator */ static Sym *__sym_malloc(void) @@ -4005,9 +4011,9 @@ ST_FUNC void unary(void) break; } case TOK___va_arg: { + CType type; if (nocode_wanted) tcc_error("statement in global scope"); - CType type; next(); skip('('); expr_eq(); @@ -5777,7 +5783,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, /* compute size */ save_parse_state(&saved_parse_state); - macro_ptr = init_str.str; + begin_macro(&init_str, 0); next(); decl_initializer(type, NULL, 0, 1, 1); /* prepare second initializer parsing */ @@ -5937,7 +5943,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, decl_initializer(type, sec, addr, 1, 0); /* restore parse state if needed */ if (init_str.str) { - tok_str_free(init_str.str); + end_macro(); restore_parse_state(&saved_parse_state); } /* patch flexible array member size back to -1, */ @@ -6018,6 +6024,7 @@ static void func_decl_list(Sym *func_sym) static void gen_function(Sym *sym) { int saved_nocode_wanted = nocode_wanted; + nocode_wanted = 0; ind = cur_text_section->data_offset; /* NOTE: we patch the symbol size later */ @@ -6034,11 +6041,9 @@ static void gen_function(Sym *sym) sym_push2(&local_stack, SYM_FIELD, 0, 0); gfunc_prolog(&sym->type); #ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check - && !strcmp(get_tok_str(sym->v, NULL), "main")) { + if (tcc_state->do_bounds_check && !strcmp(funcname, "main")) { int i; - - sym = local_stack; + Sym *sym; for (i = 0, sym = local_stack; i < 2; i++, sym = sym->prev) { if (sym->v & SYM_FIELD || sym->prev->v & SYM_FIELD) break; @@ -6075,14 +6080,16 @@ static void gen_function(Sym *sym) func_var = 0; /* for safety */ ind = 0; /* for safety */ nocode_wanted = saved_nocode_wanted; + check_vstack(); } ST_FUNC void gen_inline_functions(void) { Sym *sym; - int *str, inline_generated, i; + int inline_generated, i, ln; struct InlineFunc *fn; + ln = file->line_num; /* iterate while inline function are referenced */ for(;;) { inline_generated = 0; @@ -6092,18 +6099,17 @@ ST_FUNC void gen_inline_functions(void) if (sym && sym->c) { /* the function was used: generate its code and convert it to a normal function */ - str = fn->token_str; fn->sym = NULL; if (file) pstrcpy(file->filename, sizeof file->filename, fn->filename); sym->r = VT_SYM | VT_CONST; sym->type.t &= ~VT_INLINE; - macro_ptr = str; + begin_macro(&fn->func_str, 0); next(); cur_text_section = text_section; gen_function(sym); - macro_ptr = NULL; /* fail safe */ + end_macro(); inline_generated = 1; } @@ -6111,10 +6117,12 @@ ST_FUNC void gen_inline_functions(void) if (!inline_generated) break; } + file->line_num = ln; + /* free tokens of unused inline functions */ for (i = 0; i < tcc_state->nb_inline_fns; ++i) { fn = tcc_state->inline_fns[i]; - str = fn->token_str; - tok_str_free(str); + if (fn->sym) + tok_str_free(fn->func_str.str); } dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns); } @@ -6267,19 +6275,22 @@ static int decl0(int l, int is_for_loop_init) the compilation unit only if they are used */ if ((type.t & (VT_INLINE | VT_STATIC)) == (VT_INLINE | VT_STATIC)) { - TokenString func_str; int block_level; struct InlineFunc *fn; const char *filename; - tok_str_new(&func_str); + filename = file ? file->filename : ""; + fn = tcc_malloc(sizeof *fn + strlen(filename)); + strcpy(fn->filename, filename); + fn->sym = sym; + tok_str_new(&fn->func_str); block_level = 0; for(;;) { int t; if (tok == TOK_EOF) tcc_error("unexpected end of file"); - tok_str_add_tok(&func_str); + tok_str_add_tok(&fn->func_str); t = tok; next(); if (t == '{') { @@ -6290,13 +6301,8 @@ static int decl0(int l, int is_for_loop_init) break; } } - tok_str_add(&func_str, -1); - tok_str_add(&func_str, 0); - filename = file ? file->filename : ""; - fn = tcc_malloc(sizeof *fn + strlen(filename)); - strcpy(fn->filename, filename); - fn->sym = sym; - fn->token_str = func_str.str; + tok_str_add(&fn->func_str, -1); + tok_str_add(&fn->func_str, 0); dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn); } else { -- cgit v1.3.1