aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgrischka <grischka>2016-11-11 18:29:45 +0100
committergrischka <grischka>2016-11-11 18:29:45 +0100
commit7c28c9b13f7c924c18920b51f42b1119c3b1e2ee (patch)
treee806c9b80c58575369d39e21aa1c3e7d1d224896
parent7e7f2e5d1b40231f56fb1153a2831a216396a2ac (diff)
downloadtinycc-7c28c9b13f7c924c18920b51f42b1119c3b1e2ee.tar.gz
tinycc-7c28c9b13f7c924c18920b51f42b1119c3b1e2ee.tar.bz2
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.
-rw-r--r--tcc.h2
-rw-r--r--tccgen.c16
-rw-r--r--tccpp.c3
3 files changed, 11 insertions, 10 deletions
diff --git a/tcc.h b/tcc.h
index e536f6c..18e049e 100644
--- a/tcc.h
+++ b/tcc.h
@@ -532,7 +532,7 @@ typedef struct TokenString {
/* inline functions */
typedef struct InlineFunc {
- TokenString func_str;
+ TokenString *func_str;
Sym *sym;
char filename[1];
} InlineFunc;
diff --git a/tccgen.c b/tccgen.c
index 73371c0..427649b 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -6523,7 +6523,7 @@ static void gen_inline_functions(TCCState *s)
sym->r = VT_SYM | VT_CONST;
sym->type.t &= ~VT_INLINE;
- begin_macro(&fn->func_str, 0);
+ begin_macro(fn->func_str, 1);
next();
cur_text_section = text_section;
gen_function(sym);
@@ -6544,8 +6544,10 @@ ST_FUNC void free_inline_functions(TCCState *s)
/* free tokens of unused inline functions */
for (i = 0; i < s->nb_inline_fns; ++i) {
struct InlineFunc *fn = s->inline_fns[i];
- if (fn->sym)
- tok_str_free(fn->func_str.str);
+ if (fn->sym) {
+ tok_str_free(fn->func_str->str);
+ tal_free(tokstr_alloc, fn->func_str);
+ }
}
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));
strcpy(fn->filename, filename);
fn->sym = sym;
- tok_str_new(&fn->func_str);
+ fn->func_str = tok_str_alloc();
block_level = 0;
for(;;) {
int t;
if (tok == TOK_EOF)
tcc_error("unexpected end of file");
- tok_str_add_tok(&fn->func_str);
+ tok_str_add_tok(fn->func_str);
t = tok;
next();
if (t == '{') {
@@ -6719,8 +6721,8 @@ static int decl0(int l, int is_for_loop_init)
break;
}
}
- tok_str_add(&fn->func_str, -1);
- tok_str_add(&fn->func_str, 0);
+ 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 {
diff --git a/tccpp.c b/tccpp.c
index b75603f..0bfeaeb 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -1124,8 +1124,7 @@ ST_FUNC void end_macro(void)
str->alloc = 3; /* just mark as finished */
} else {
tok_str_free(str->str);
- if (str->alloc == 1)
- tal_free(tokstr_alloc, str);
+ tal_free(tokstr_alloc, str);
}
}