tccgen: inline_functions double free fix

Fix double free of the inline function token_string which
could happen when an error/longjmp occurred while compiling
the inline function.
master
grischka 2016-11-11 18:29:45 +01:00
parent 7e7f2e5d1b
commit 7c28c9b13f
3 changed files with 11 additions and 10 deletions

2
tcc.h
View File

@ -532,7 +532,7 @@ typedef struct TokenString {
/* inline functions */ /* inline functions */
typedef struct InlineFunc { typedef struct InlineFunc {
TokenString func_str; TokenString *func_str;
Sym *sym; Sym *sym;
char filename[1]; char filename[1];
} InlineFunc; } InlineFunc;

View File

@ -6523,7 +6523,7 @@ static void gen_inline_functions(TCCState *s)
sym->r = VT_SYM | VT_CONST; sym->r = VT_SYM | VT_CONST;
sym->type.t &= ~VT_INLINE; sym->type.t &= ~VT_INLINE;
begin_macro(&fn->func_str, 0); begin_macro(fn->func_str, 1);
next(); next();
cur_text_section = text_section; cur_text_section = text_section;
gen_function(sym); gen_function(sym);
@ -6544,8 +6544,10 @@ ST_FUNC void free_inline_functions(TCCState *s)
/* free tokens of unused inline functions */ /* free tokens of unused inline functions */
for (i = 0; i < s->nb_inline_fns; ++i) { for (i = 0; i < s->nb_inline_fns; ++i) {
struct InlineFunc *fn = s->inline_fns[i]; struct InlineFunc *fn = s->inline_fns[i];
if (fn->sym) if (fn->sym) {
tok_str_free(fn->func_str.str); tok_str_free(fn->func_str->str);
tal_free(tokstr_alloc, fn->func_str);
}
} }
dynarray_reset(&s->inline_fns, &s->nb_inline_fns); dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
} }
@ -6701,14 +6703,14 @@ static int decl0(int l, int is_for_loop_init)
fn = tcc_malloc(sizeof *fn + strlen(filename)); fn = tcc_malloc(sizeof *fn + strlen(filename));
strcpy(fn->filename, filename); strcpy(fn->filename, filename);
fn->sym = sym; fn->sym = sym;
tok_str_new(&fn->func_str); fn->func_str = tok_str_alloc();
block_level = 0; block_level = 0;
for(;;) { for(;;) {
int t; int t;
if (tok == TOK_EOF) if (tok == TOK_EOF)
tcc_error("unexpected end of file"); tcc_error("unexpected end of file");
tok_str_add_tok(&fn->func_str); tok_str_add_tok(fn->func_str);
t = tok; t = tok;
next(); next();
if (t == '{') { if (t == '{') {
@ -6719,8 +6721,8 @@ static int decl0(int l, int is_for_loop_init)
break; break;
} }
} }
tok_str_add(&fn->func_str, -1); tok_str_add(fn->func_str, -1);
tok_str_add(&fn->func_str, 0); tok_str_add(fn->func_str, 0);
dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn); dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
} else { } else {

View File

@ -1124,8 +1124,7 @@ ST_FUNC void end_macro(void)
str->alloc = 3; /* just mark as finished */ str->alloc = 3; /* just mark as finished */
} else { } else {
tok_str_free(str->str); tok_str_free(str->str);
if (str->alloc == 1) tal_free(tokstr_alloc, str);
tal_free(tokstr_alloc, str);
} }
} }