From: Vlad Vissoultchev Date: Mon, 11 Apr 2016 01:26:32 +0300 Subject: Fix pragma once guard when compiling multiple source files When compiling multiple source files directly to executable cached include files guard was incorrectly checked for TOK_once in ifndef_macro member. If two source files included the same header guarded by pragma once, then the second one erroneously skipped it as `cached_includes` is not cleared on second `tcc_compile`
Unified · Split
| @@ -344,7 +344,7 @@ int main(int argc, char **argv) · 343 unmodified lines | |||
| 344 | tcc_parse_args(s, argc - 1, argv + 1); | 344 | tcc_parse_args(s, argc - 1, argv + 1); |
| 345 | tcc_set_environment(s); | 345 | tcc_set_environment(s); |
| 346 | if (s->output_type != TCC_OUTPUT_OBJ) | 346 | if (s->output_type != TCC_OUTPUT_OBJ) |
| 347 | tcc_error("interlnal error"); | 347 | tcc_error("internal error"); |
| 348 | tcc_set_output_type(s, s->output_type); | 348 | tcc_set_output_type(s, s->output_type); |
| 349 | } | 349 | } |
| 350 | } | 350 | } |
| @@ -1471,8 +1471,11 @@ static void pragma_parse(TCCState *s1) · 1470 unmodified lines | |||
| 1471 | tcc_warning("unbalanced #pragma pop_macro"); | 1471 | tcc_warning("unbalanced #pragma pop_macro"); |
| 1472 | 1472 | ||
| 1473 | } else if (tok == TOK_once) { | 1473 | } else if (tok == TOK_once) { |
| 1474 | add_cached_include(s1, file->filename, TOK_once); | 1474 | char buf1[sizeof file->filename]; |
| 1475 | 1475 | ||
| 1476 | pstrcpy(buf1, sizeof(buf1), "#once#"); | ||
| 1477 | pstrcat(buf1, sizeof(buf1), file->filename); | ||
| 1478 | add_cached_include(s1, file->filename, tok_alloc(buf1, strlen(buf1))->tok); | ||
| 1476 | } else if (s1->ppfp) { | 1479 | } else if (s1->ppfp) { |
| 1477 | /* tcc -E: keep pragmas below unchanged */ | 1480 | /* tcc -E: keep pragmas below unchanged */ |
| 1478 | unget_tok(' '); | 1481 | unget_tok(' '); |
| @@ -1670,7 +1673,7 @@ ST_FUNC void preprocess(int is_bof) · 191 unmodified lines | |||
| 1670 | 1673 | ||
| 1671 | pstrcat(buf1, sizeof(buf1), buf); | 1674 | pstrcat(buf1, sizeof(buf1), buf); |
| 1672 | e = search_cached_include(s1, buf1); | 1675 | e = search_cached_include(s1, buf1); |
| 1673 | if (e && (define_find(e->ifndef_macro) || e->ifndef_macro == TOK_once)) { | 1676 | if (e && define_find(e->ifndef_macro)) { |
| 1674 | /* no need to parse the include because the 'ifndef macro' | 1677 | /* no need to parse the include because the 'ifndef macro' |
| 1675 | is defined */ | 1678 | is defined */ |
| 1676 | #ifdef INC_DEBUG | 1679 | #ifdef INC_DEBUG |