avoid memory leaks with lost CStrings on stack after errors. tccpp.c: - use/abuse static Cstring tokcstr where possible tccgen.c: - use/abuse static Cstring initstr where possible tcc.h/libtcc.a: - add 'stk_data' array to track memory pointer on stack - add macros stk_push/pop() and cstr_new/free_s() tccasm.c: - use that - use char[16] instead of char* for op.constraint
Unified · Split
| @@ -68,6 +68,9 @@ · 67 unmodified lines | ||
| 68 | 68 | /* XXX: get rid of this ASAP (or maybe not) */ |
| 69 | 69 | ST_DATA struct TCCState *tcc_state; |
| 70 | 70 | TCC_SEM(static tcc_compile_sem); |
| 71 | +/* an array of pointers to memory to be free'd after errors */ | |
| 72 | +ST_DATA void** stk_data; | |
| 73 | +ST_DATA int nb_stk_data; | |
| 71 | 74 | |
| 72 | 75 | /********************************************************/ |
| 73 | 76 | #ifdef _WIN32 |
| @@ -609,8 +612,11 @@ static void error1(int mode, const char *fmt, va_list ap) · 535 unmodified lines | ||
| 609 | 612 | cstr_free(&cs); |
| 610 | 613 | if (mode != ERROR_WARN) |
| 611 | 614 | s1->nb_errors++; |
| 612 | − if (mode == ERROR_ERROR && s1->error_set_jmp_enabled) | |
| 615 | + if (mode == ERROR_ERROR && s1->error_set_jmp_enabled) { | |
| 616 | + while (nb_stk_data) | |
| 617 | + tcc_free(*(void**)stk_data[--nb_stk_data]); | |
| 613 | 618 | longjmp(s1->error_jmp_buf, 1); |
| 619 | + } | |
| 614 | 620 | } |
| 615 | 621 | |
| 616 | 622 | LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc error_func) |
| @@ -495,6 +495,7 @@ typedef struct CString { · 494 unmodified lines | ||
| 495 | 495 | int size; /* size in bytes */ |
| 496 | 496 | int size_allocated; |
| 497 | 497 | void *data; /* either 'char *' or 'nwchar_t *' */ |
| 498 | + struct CString *prev; | |
| 498 | 499 | } CString; |
| 499 | 500 | |
| 500 | 501 | /* type definition */ |
| @@ -733,7 +734,7 @@ typedef struct ExprValue { · 232 unmodified lines | ||
| 733 | 734 | #define MAX_ASM_OPERANDS 30 |
| 734 | 735 | typedef struct ASMOperand { |
| 735 | 736 | int id; /* GCC 3 optional identifier (0 if number only supported) */ |
| 736 | − char *constraint; | |
| 737 | + char constraint[16]; | |
| 737 | 738 | char asm_str[16]; /* computed asm string for operand */ |
| 738 | 739 | SValue *vt; /* C value of the expression */ |
| 739 | 740 | int ref_index; /* if >= 0, gives reference to a output constraint */ |
| @@ -1208,6 +1209,8 @@ enum tcc_token { · 468 unmodified lines | ||
| 1208 | 1209 | /* ------------ libtcc.c ------------ */ |
| 1209 | 1210 | |
| 1210 | 1211 | ST_DATA struct TCCState *tcc_state; |
| 1212 | +ST_DATA void** stk_data; | |
| 1213 | +ST_DATA int nb_stk_data; | |
| 1211 | 1214 | |
| 1212 | 1215 | /* public functions currently used by the tcc main function */ |
| 1213 | 1216 | ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s); |
| @@ -1257,11 +1260,17 @@ ST_FUNC void cstr_free(CString *cstr); · 43 unmodified lines | ||
| 1257 | 1260 | ST_FUNC int cstr_printf(CString *cs, const char *fmt, ...) PRINTF_LIKE(2,3); |
| 1258 | 1261 | ST_FUNC int cstr_vprintf(CString *cstr, const char *fmt, va_list ap); |
| 1259 | 1262 | ST_FUNC void cstr_reset(CString *cstr); |
| 1260 | − | |
| 1261 | 1263 | ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen); |
| 1262 | 1264 | ST_FUNC int tcc_open(TCCState *s1, const char *filename); |
| 1263 | 1265 | ST_FUNC void tcc_close(void); |
| 1264 | 1266 | |
| 1267 | +/* mark a memory pointer on stack for cleanup after errors */ | |
| 1268 | +#define stk_push(p) dynarray_add(&stk_data, &nb_stk_data, p) | |
| 1269 | +#define stk_pop() (--nb_stk_data) | |
| 1270 | +/* mark CString on stack for cleanup errors */ | |
| 1271 | +#define cstr_new_s(cstr) (cstr_new(cstr), stk_push(&(cstr)->data)) | |
| 1272 | +#define cstr_free_s(cstr) (cstr_free(cstr), stk_pop()) | |
| 1273 | + | |
| 1265 | 1274 | ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags); |
| 1266 | 1275 | /* flags: */ |
| 1267 | 1276 | #define AFF_PRINT_ERROR 0x10 /* print error if file not found */ |
| @@ -1483,8 +1492,8 @@ ST_FUNC int type_size(CType *type, int *a); · 215 unmodified lines | ||
| 1483 | 1492 | ST_FUNC void mk_pointer(CType *type); |
| 1484 | 1493 | ST_FUNC void vstore(void); |
| 1485 | 1494 | ST_FUNC void inc(int post, int c); |
| 1486 | −ST_FUNC void parse_mult_str (CString *astr, const char *msg); | |
| 1487 | −ST_FUNC void parse_asm_str(CString *astr); | |
| 1495 | +ST_FUNC CString* parse_mult_str(const char *msg); | |
| 1496 | +ST_FUNC CString* parse_asm_str(void); | |
| 1488 | 1497 | ST_FUNC void indir(void); |
| 1489 | 1498 | ST_FUNC void unary(void); |
| 1490 | 1499 | ST_FUNC void gexpr(void); |
| @@ -1064,15 +1064,12 @@ ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, · 1063 unmodified lines | ||
| 1064 | 1064 | } |
| 1065 | 1065 | |
| 1066 | 1066 | static void subst_asm_operands(ASMOperand *operands, int nb_operands, |
| 1067 | − CString *out_str, CString *in_str) | |
| 1067 | + CString *out_str, const char *str) | |
| 1068 | 1068 | { |
| 1069 | 1069 | int c, index, modifier; |
| 1070 | − const char *str; | |
| 1071 | 1070 | ASMOperand *op; |
| 1072 | 1071 | SValue sv; |
| 1073 | 1072 | |
| 1074 | − cstr_new(out_str); | |
| 1075 | − str = in_str->data; | |
| 1076 | 1073 | for(;;) { |
| 1077 | 1074 | c = *str++; |
| 1078 | 1075 | if (c == '%') { |
| @@ -1118,11 +1115,11 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr, · 39 unmodified lines | ||
| 1118 | 1115 | { |
| 1119 | 1116 | ASMOperand *op; |
| 1120 | 1117 | int nb_operands; |
| 1118 | + char* astr; | |
| 1121 | 1119 | |
| 1122 | 1120 | if (tok != ':') { |
| 1123 | 1121 | nb_operands = *nb_operands_ptr; |
| 1124 | 1122 | for(;;) { |
| 1125 | − CString astr; | |
| 1126 | 1123 | if (nb_operands >= MAX_ASM_OPERANDS) |
| 1127 | 1124 | tcc_error("too many asm operands"); |
| 1128 | 1125 | op = &operands[nb_operands++]; |
| @@ -1135,10 +1132,8 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr, · 6 unmodified lines | ||
| 1135 | 1132 | next(); |
| 1136 | 1133 | skip(']'); |
| 1137 | 1134 | } |
| 1138 | − parse_mult_str(&astr, "string constant"); | |
| 1139 | − op->constraint = tcc_malloc(astr.size); | |
| 1140 | − strcpy(op->constraint, astr.data); | |
| 1141 | − cstr_free(&astr); | |
| 1135 | + astr = parse_mult_str("string constant")->data; | |
| 1136 | + pstrcpy(op->constraint, sizeof op->constraint, astr); | |
| 1142 | 1137 | skip('('); |
| 1143 | 1138 | gexpr(); |
| 1144 | 1139 | if (is_output) { |
| @@ -1171,7 +1166,8 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr, · 26 unmodified lines | ||
| 1171 | 1166 | /* parse the GCC asm() instruction */ |
| 1172 | 1167 | ST_FUNC void asm_instr(void) |
| 1173 | 1168 | { |
| 1174 | − CString astr, astr1; | |
| 1169 | + CString astr, *astr1; | |
| 1170 | + | |
| 1175 | 1171 | ASMOperand operands[MAX_ASM_OPERANDS]; |
| 1176 | 1172 | int nb_outputs, nb_operands, i, must_subst, out_reg, nb_labels; |
| 1177 | 1173 | uint8_t clobber_regs[NB_ASM_REGS]; |
| @@ -1183,7 +1179,11 @@ ST_FUNC void asm_instr(void) · 5 unmodified lines | ||
| 1183 | 1179 | || tok == TOK_GOTO) { |
| 1184 | 1180 | next(); |
| 1185 | 1181 | } |
| 1186 | − parse_asm_str(&astr); | |
| 1182 | + | |
| 1183 | + astr1 = parse_asm_str(); | |
| 1184 | + cstr_new_s(&astr); | |
| 1185 | + cstr_cat(&astr, astr1->data, astr1->size); | |
| 1186 | + | |
| 1187 | 1187 | nb_operands = 0; |
| 1188 | 1188 | nb_outputs = 0; |
| 1189 | 1189 | nb_labels = 0; |
| @@ -1273,13 +1273,14 @@ ST_FUNC void asm_instr(void) · 83 unmodified lines | ||
| 1273 | 1273 | printf("asm: \"%s\"\n", (char *)astr.data); |
| 1274 | 1274 | #endif |
| 1275 | 1275 | if (must_subst) { |
| 1276 | − subst_asm_operands(operands, nb_operands + nb_labels, &astr1, &astr); | |
| 1277 | − cstr_free(&astr); | |
| 1278 | − } else { | |
| 1279 | − astr1 = astr; | |
| 1276 | + cstr_reset(astr1); | |
| 1277 | + cstr_cat(astr1, astr.data, astr.size); | |
| 1278 | + cstr_reset(&astr); | |
| 1279 | + subst_asm_operands(operands, nb_operands + nb_labels, &astr, astr1->data); | |
| 1280 | 1280 | } |
| 1281 | + | |
| 1281 | 1282 | #ifdef ASM_DEBUG |
| 1282 | − printf("subst_asm: \"%s\"\n", (char *)astr1.data); | |
| 1283 | + printf("subst_asm: \"%s\"\n", (char *)astr.data); | |
| 1283 | 1284 | #endif |
| 1284 | 1285 | |
| 1285 | 1286 | /* generate loads */ |
| @@ -1290,7 +1291,8 @@ ST_FUNC void asm_instr(void) · 4 unmodified lines | ||
| 1290 | 1291 | bleed out to surrounding code. */ |
| 1291 | 1292 | sec = cur_text_section; |
| 1292 | 1293 | /* assemble the string with tcc internal assembler */ |
| 1293 | − tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1, 0); | |
| 1294 | + tcc_assemble_inline(tcc_state, astr.data, astr.size - 1, 0); | |
| 1295 | + cstr_free_s(&astr); | |
| 1294 | 1296 | if (sec != cur_text_section) { |
| 1295 | 1297 | tcc_warning("inline asm tries to change current section"); |
| 1296 | 1298 | use_section1(tcc_state, sec); |
| @@ -1305,23 +1307,20 @@ ST_FUNC void asm_instr(void) · 8 unmodified lines | ||
| 1305 | 1307 | |
| 1306 | 1308 | /* free everything */ |
| 1307 | 1309 | for(i=0;i<nb_operands;i++) { |
| 1308 | − ASMOperand *op; | |
| 1309 | − op = &operands[i]; | |
| 1310 | − tcc_free(op->constraint); | |
| 1311 | 1310 | vpop(); |
| 1312 | 1311 | } |
| 1313 | − cstr_free(&astr1); | |
| 1312 | + | |
| 1314 | 1313 | } |
| 1315 | 1314 | |
| 1316 | 1315 | ST_FUNC void asm_global_instr(void) |
| 1317 | 1316 | { |
| 1318 | − CString astr; | |
| 1317 | + CString *astr; | |
| 1319 | 1318 | int saved_nocode_wanted = nocode_wanted; |
| 1320 | 1319 | |
| 1321 | 1320 | /* Global asm blocks are always emitted. */ |
| 1322 | 1321 | nocode_wanted = 0; |
| 1323 | 1322 | next(); |
| 1324 | − parse_asm_str(&astr); | |
| 1323 | + astr = parse_asm_str(); | |
| 1325 | 1324 | skip(')'); |
| 1326 | 1325 | /* NOTE: we do not eat the ';' so that we can restore the current |
| 1327 | 1326 | token after the assembler parsing */ |
| @@ -1335,14 +1334,13 @@ ST_FUNC void asm_global_instr(void) · 7 unmodified lines | ||
| 1335 | 1334 | ind = cur_text_section->data_offset; |
| 1336 | 1335 | |
| 1337 | 1336 | /* assemble the string with tcc internal assembler */ |
| 1338 | − tcc_assemble_inline(tcc_state, astr.data, astr.size - 1, 1); | |
| 1337 | + tcc_assemble_inline(tcc_state, astr->data, astr->size - 1, 1); | |
| 1339 | 1338 | |
| 1340 | 1339 | cur_text_section->data_offset = ind; |
| 1341 | 1340 | |
| 1342 | 1341 | /* restore the current C token */ |
| 1343 | 1342 | next(); |
| 1344 | 1343 | |
| 1345 | − cstr_free(&astr); | |
| 1346 | 1344 | nocode_wanted = saved_nocode_wanted; |
| 1347 | 1345 | } |
| 1348 | 1346 | |
| @@ -402,7 +402,6 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 401 unmodified lines | ||
| 402 | 402 | ST_FUNC void tccgen_finish(TCCState *s1) |
| 403 | 403 | { |
| 404 | 404 | tcc_debug_end(s1); /* just in case of errors: free memory */ |
| 405 | − cstr_free(&initstr); | |
| 406 | 405 | free_inline_functions(s1); |
| 407 | 406 | sym_pop(&global_stack, NULL, 0); |
| 408 | 407 | sym_pop(&local_stack, NULL, 0); |
| @@ -412,6 +411,8 @@ ST_FUNC void tccgen_finish(TCCState *s1) · 3 unmodified lines | ||
| 412 | 411 | dynarray_reset(&sym_pools, &nb_sym_pools); |
| 413 | 412 | sym_free_first = NULL; |
| 414 | 413 | global_label_stack = local_label_stack = NULL; |
| 414 | + cstr_free(&initstr); | |
| 415 | + dynarray_reset(&stk_data, &nb_stk_data); | |
| 415 | 416 | } |
| 416 | 417 | |
| 417 | 418 | /* ------------------------------------------------------------------------- */ |
| @@ -3756,18 +3757,19 @@ ST_FUNC void inc(int post, int c) · 3338 unmodified lines | ||
| 3756 | 3757 | vpop(); /* if post op, return saved value */ |
| 3757 | 3758 | } |
| 3758 | 3759 | |
| 3759 | −ST_FUNC void parse_mult_str (CString *astr, const char *msg) | |
| 3760 | +ST_FUNC CString* parse_mult_str (const char *msg) | |
| 3760 | 3761 | { |
| 3761 | 3762 | /* read the string */ |
| 3762 | 3763 | if (tok != TOK_STR) |
| 3763 | 3764 | expect(msg); |
| 3764 | − cstr_new(astr); | |
| 3765 | + cstr_reset(&initstr); | |
| 3765 | 3766 | while (tok == TOK_STR) { |
| 3766 | 3767 | /* XXX: add \0 handling too ? */ |
| 3767 | − cstr_cat(astr, tokc.str.data, -1); | |
| 3768 | + cstr_cat(&initstr, tokc.str.data, -1); | |
| 3768 | 3769 | next(); |
| 3769 | 3770 | } |
| 3770 | − cstr_ccat(astr, '\0'); | |
| 3771 | + cstr_ccat(&initstr, '\0'); | |
| 3772 | + return &initstr; | |
| 3771 | 3773 | } |
| 3772 | 3774 | |
| 3773 | 3775 | /* If I is >= 1 and a power of two, returns log2(i)+1. |
| @@ -3792,7 +3794,7 @@ ST_FUNC int exact_log2p1(int i) · 18 unmodified lines | ||
| 3792 | 3794 | static void parse_attribute(AttributeDef *ad) |
| 3793 | 3795 | { |
| 3794 | 3796 | int t, n; |
| 3795 | − CString astr; | |
| 3797 | + char *astr; | |
| 3796 | 3798 | |
| 3797 | 3799 | redo: |
| 3798 | 3800 | if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2) |
| @@ -3839,37 +3841,33 @@ redo: · 40 unmodified lines | ||
| 3839 | 3841 | case TOK_SECTION1: |
| 3840 | 3842 | case TOK_SECTION2: |
| 3841 | 3843 | skip('('); |
| 3842 | − parse_mult_str(&astr, "section name"); | |
| 3843 | − ad->section = find_section(tcc_state, (char *)astr.data); | |
| 3844 | + astr = parse_mult_str("section name")->data; | |
| 3845 | + ad->section = find_section(tcc_state, astr); | |
| 3844 | 3846 | skip(')'); |
| 3845 | − cstr_free(&astr); | |
| 3846 | 3847 | break; |
| 3847 | 3848 | case TOK_ALIAS1: |
| 3848 | 3849 | case TOK_ALIAS2: |
| 3849 | 3850 | skip('('); |
| 3850 | − parse_mult_str(&astr, "alias(\"target\")"); | |
| 3851 | − ad->alias_target = /* save string as token, for later */ | |
| 3852 | − tok_alloc((char*)astr.data, astr.size-1)->tok; | |
| 3851 | + astr = parse_mult_str("alias(\"target\")")->data; | |
| 3852 | + /* save string as token, for later */ | |
| 3853 | + ad->alias_target = tok_alloc_const(astr); | |
| 3853 | 3854 | skip(')'); |
| 3854 | − cstr_free(&astr); | |
| 3855 | 3855 | break; |
| 3856 | 3856 | case TOK_VISIBILITY1: |
| 3857 | 3857 | case TOK_VISIBILITY2: |
| 3858 | 3858 | skip('('); |
| 3859 | − parse_mult_str(&astr, | |
| 3860 | − "visibility(\"default|hidden|internal|protected\")"); | |
| 3861 | − if (!strcmp (astr.data, "default")) | |
| 3859 | + astr = parse_mult_str("visibility(\"default|hidden|internal|protected\")")->data; | |
| 3860 | + if (!strcmp (astr, "default")) | |
| 3862 | 3861 | ad->a.visibility = STV_DEFAULT; |
| 3863 | − else if (!strcmp (astr.data, "hidden")) | |
| 3862 | + else if (!strcmp (astr, "hidden")) | |
| 3864 | 3863 | ad->a.visibility = STV_HIDDEN; |
| 3865 | − else if (!strcmp (astr.data, "internal")) | |
| 3864 | + else if (!strcmp (astr, "internal")) | |
| 3866 | 3865 | ad->a.visibility = STV_INTERNAL; |
| 3867 | − else if (!strcmp (astr.data, "protected")) | |
| 3866 | + else if (!strcmp (astr, "protected")) | |
| 3868 | 3867 | ad->a.visibility = STV_PROTECTED; |
| 3869 | 3868 | else |
| 3870 | 3869 | expect("visibility(\"default|hidden|internal|protected\")"); |
| 3871 | 3870 | skip(')'); |
| 3872 | − cstr_free(&astr); | |
| 3873 | 3871 | break; |
| 3874 | 3872 | case TOK_ALIGNED1: |
| 3875 | 3873 | case TOK_ALIGNED2: |
| @@ -4818,26 +4816,25 @@ static inline void convert_parameter_type(CType *pt) · 942 unmodified lines | ||
| 4818 | 4816 | } |
| 4819 | 4817 | } |
| 4820 | 4818 | |
| 4821 | −ST_FUNC void parse_asm_str(CString *astr) | |
| 4819 | +ST_FUNC CString* parse_asm_str(void) | |
| 4822 | 4820 | { |
| 4823 | 4821 | skip('('); |
| 4824 | − parse_mult_str(astr, "string constant"); | |
| 4822 | + return parse_mult_str("string constant"); | |
| 4825 | 4823 | } |
| 4826 | 4824 | |
| 4827 | 4825 | /* Parse an asm label and return the token */ |
| 4828 | 4826 | static int asm_label_instr(void) |
| 4829 | 4827 | { |
| 4830 | 4828 | int v; |
| 4831 | − CString astr; | |
| 4829 | + char *astr; | |
| 4832 | 4830 | |
| 4833 | 4831 | next(); |
| 4834 | − parse_asm_str(&astr); | |
| 4832 | + astr = parse_asm_str()->data; | |
| 4835 | 4833 | skip(')'); |
| 4836 | 4834 | #ifdef ASM_DEBUG |
| 4837 | − printf("asm_alias: \"%s\"\n", (char *)astr.data); | |
| 4835 | + printf("asm_alias: \"%s\"\n", astr); | |
| 4838 | 4836 | #endif |
| 4839 | − v = tok_alloc(astr.data, astr.size - 1)->tok; | |
| 4840 | − cstr_free(&astr); | |
| 4837 | + v = tok_alloc_const(astr); | |
| 4841 | 4838 | return v; |
| 4842 | 4839 | } |
| 4843 | 4840 | |
| @@ -8357,29 +8354,23 @@ static void free_inline_functions(TCCState *s) · 3513 unmodified lines | ||
| 8357 | 8354 | dynarray_reset(&s->inline_fns, &s->nb_inline_fns); |
| 8358 | 8355 | } |
| 8359 | 8356 | |
| 8360 | −static void do_Static_assert(void){ | |
| 8361 | − CString error_str; | |
| 8357 | +static void do_Static_assert(void) | |
| 8358 | +{ | |
| 8362 | 8359 | int c; |
| 8360 | + const char *msg; | |
| 8363 | 8361 | |
| 8364 | 8362 | next(); |
| 8365 | 8363 | skip('('); |
| 8366 | 8364 | c = expr_const(); |
| 8367 | − | |
| 8368 | − if (tok == ')') { | |
| 8369 | − if (!c) | |
| 8370 | − tcc_error("_Static_assert fail"); | |
| 8371 | − next(); | |
| 8372 | − goto static_assert_out; | |
| 8365 | + msg = "_Static_assert fail"; | |
| 8366 | + if (tok == ',') { | |
| 8367 | + next(); | |
| 8368 | + msg = parse_mult_str("string constant")->data; | |
| 8373 | 8369 | } |
| 8374 | − | |
| 8375 | − skip(','); | |
| 8376 | − parse_mult_str(&error_str, "string constant"); | |
| 8377 | − if (c == 0) | |
| 8378 | − tcc_error("%s", (char *)error_str.data); | |
| 8379 | − cstr_free(&error_str); | |
| 8380 | 8370 | skip(')'); |
| 8381 | − static_assert_out: | |
| 8382 | − skip(';'); | |
| 8371 | + if (c == 0) | |
| 8372 | + tcc_error("%s", msg); | |
| 8373 | + skip(';'); | |
| 8383 | 8374 | } |
| 8384 | 8375 | |
| 8385 | 8376 | /* 'l' is VT_LOCAL or VT_CONST to define default storage type |
| @@ -8393,10 +8384,11 @@ static int decl(int l) · 7 unmodified lines | ||
| 8393 | 8384 | AttributeDef ad, adbase; |
| 8394 | 8385 | |
| 8395 | 8386 | while (1) { |
| 8396 | − if (tok == TOK_STATIC_ASSERT) { | |
| 8397 | − do_Static_assert(); | |
| 8398 | − continue; | |
| 8399 | − } | |
| 8387 | + | |
| 8388 | + if (tok == TOK_STATIC_ASSERT) { | |
| 8389 | + do_Static_assert(); | |
| 8390 | + continue; | |
| 8391 | + } | |
| 8400 | 8392 | |
| 8401 | 8393 | oldint = 0; |
| 8402 | 8394 | if (!parse_btype(&btype, &adbase, l == VT_LOCAL)) { |
| @@ -45,7 +45,6 @@ ST_DATA TokenSym **table_ident; · 44 unmodified lines | ||
| 45 | 45 | static TokenSym *hash_ident[TOK_HASH_SIZE]; |
| 46 | 46 | static char token_buf[STRING_MAX_SIZE + 1]; |
| 47 | 47 | static CString cstr_buf; |
| 48 | −static CString macro_equal_buf; | |
| 49 | 48 | static TokenString tokstr_buf; |
| 50 | 49 | static unsigned char isidnum_table[256 - CH_EOF]; |
| 51 | 50 | static int pp_debug_tok, pp_debug_symv; |
| @@ -399,7 +398,6 @@ ST_FUNC void cstr_new(CString *cstr) · 347 unmodified lines | ||
| 399 | 398 | ST_FUNC void cstr_free(CString *cstr) |
| 400 | 399 | { |
| 401 | 400 | tcc_free(cstr->data); |
| 402 | − cstr_new(cstr); | |
| 403 | 401 | } |
| 404 | 402 | |
| 405 | 403 | /* reset string to empty */ |
| @@ -1273,12 +1271,11 @@ static int macro_is_equal(const int *a, const int *b) · 867 unmodified lines | ||
| 1273 | 1271 | return 1; |
| 1274 | 1272 | |
| 1275 | 1273 | while (*a && *b) { |
| 1276 | − /* first time preallocate macro_equal_buf, next time only reset position to start */ | |
| 1277 | − cstr_reset(¯o_equal_buf); | |
| 1274 | + cstr_reset(&tokcstr); | |
| 1278 | 1275 | TOK_GET(&t, &a, &cv); |
| 1279 | − cstr_cat(¯o_equal_buf, get_tok_str(t, &cv), 0); | |
| 1276 | + cstr_cat(&tokcstr, get_tok_str(t, &cv), 0); | |
| 1280 | 1277 | TOK_GET(&t, &b, &cv); |
| 1281 | − if (strcmp(macro_equal_buf.data, get_tok_str(t, &cv))) | |
| 1278 | + if (strcmp(tokcstr.data, get_tok_str(t, &cv))) | |
| 1282 | 1279 | return 0; |
| 1283 | 1280 | } |
| 1284 | 1281 | return !(*a || *b); |
| @@ -1348,14 +1345,15 @@ search_cached_include(TCCState *s1, const char *filename, int add); · 63 unmodified lines | ||
| 1348 | 1345 | static int parse_include(TCCState *s1, int do_next, int test) |
| 1349 | 1346 | { |
| 1350 | 1347 | int c, i; |
| 1351 | − CString cs; | |
| 1352 | 1348 | char name[1024], buf[1024], *p; |
| 1353 | 1349 | CachedInclude *e; |
| 1354 | 1350 | |
| 1355 | − cstr_new(&cs); | |
| 1356 | 1351 | c = skip_spaces(); |
| 1357 | 1352 | if (c == '<' || c == '\"') { |
| 1358 | − file->buf_ptr = parse_pp_string(file->buf_ptr, c == '<' ? '>' : c, &cs); | |
| 1353 | + cstr_reset(&tokcstr); | |
| 1354 | + file->buf_ptr = parse_pp_string(file->buf_ptr, c == '<' ? '>' : c, &tokcstr); | |
| 1355 | + i = tokcstr.size; | |
| 1356 | + pstrncpy(name, tokcstr.data, i >= sizeof name ? sizeof name - 1 : i); | |
| 1359 | 1357 | next_nomacro(); |
| 1360 | 1358 | } else { |
| 1361 | 1359 | /* computed #include : concatenate tokens until result is one of |
| @@ -1363,24 +1361,22 @@ static int parse_include(TCCState *s1, int do_next, int test) · 1 unmodified line | ||
| 1363 | 1361 | parse_flags = PARSE_FLAG_PREPROCESS |
| 1364 | 1362 | | PARSE_FLAG_LINEFEED |
| 1365 | 1363 | | (parse_flags & PARSE_FLAG_ASM_FILE); |
| 1364 | + name[0] = 0; | |
| 1366 | 1365 | for (;;) { |
| 1367 | 1366 | next(); |
| 1368 | − p = cs.data, i = cs.size - 1; | |
| 1367 | + p = name, i = strlen(p) - 1; | |
| 1369 | 1368 | if (i > 0 |
| 1370 | 1369 | && ((p[0] == '"' && p[i] == '"') |
| 1371 | 1370 | || (p[0] == '<' && p[i] == '>'))) |
| 1372 | 1371 | break; |
| 1373 | 1372 | if (tok == TOK_LINEFEED) |
| 1374 | 1373 | tcc_error("'#include' expects \"FILENAME\" or <FILENAME>"); |
| 1375 | − cstr_cat(&cs, get_tok_str(tok, &tokc), -1); | |
| 1374 | + pstrcat(name, sizeof name, get_tok_str(tok, &tokc)); | |
| 1376 | 1375 | } |
| 1377 | 1376 | c = p[0]; |
| 1378 | 1377 | /* remove '<>|""' */ |
| 1379 | − memmove(p, p + 1, cs.size -= 2); | |
| 1378 | + memmove(p, p + 1, i - 1), p[i - 1] = 0; | |
| 1380 | 1379 | } |
| 1381 | − cstr_ccat(&cs, '\0'); | |
| 1382 | − pstrcpy(name, sizeof name, cs.data); | |
| 1383 | − cstr_free(&cs); | |
| 1384 | 1380 | |
| 1385 | 1381 | i = do_next ? file->include_next_index : -1; |
| 1386 | 1382 | for (;;) { |
| @@ -2934,7 +2930,6 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 1547 unmodified lines | ||
| 2934 | 2930 | Sym *s; |
| 2935 | 2931 | CValue cval; |
| 2936 | 2932 | TokenString str; |
| 2937 | − CString cstr; | |
| 2938 | 2933 | |
| 2939 | 2934 | tok_str_new(&str); |
| 2940 | 2935 | t0 = t1 = 0; |
| @@ -2949,8 +2944,8 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 8 unmodified lines | ||
| 2949 | 2944 | goto bad_stringy; |
| 2950 | 2945 | s = sym_find2(args, t); |
| 2951 | 2946 | if (s) { |
| 2952 | − cstr_new(&cstr); | |
| 2953 | − cstr_ccat(&cstr, '\"'); | |
| 2947 | + cstr_reset(&tokcstr); | |
| 2948 | + cstr_ccat(&tokcstr, '\"'); | |
| 2954 | 2949 | st = s->d; |
| 2955 | 2950 | spc = 0; |
| 2956 | 2951 | while (*st >= 0) { |
| @@ -2961,24 +2956,23 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 4 unmodified lines | ||
| 2961 | 2956 | const char *s = get_tok_str(t, &cval); |
| 2962 | 2957 | while (*s) { |
| 2963 | 2958 | if (t == TOK_PPSTR && *s != '\'') |
| 2964 | − add_char(&cstr, *s); | |
| 2959 | + add_char(&tokcstr, *s); | |
| 2965 | 2960 | else |
| 2966 | − cstr_ccat(&cstr, *s); | |
| 2961 | + cstr_ccat(&tokcstr, *s); | |
| 2967 | 2962 | ++s; |
| 2968 | 2963 | } |
| 2969 | 2964 | } |
| 2970 | 2965 | } |
| 2971 | − cstr.size -= spc; | |
| 2972 | − cstr_ccat(&cstr, '\"'); | |
| 2973 | − cstr_ccat(&cstr, '\0'); | |
| 2966 | + tokcstr.size -= spc; | |
| 2967 | + cstr_ccat(&tokcstr, '\"'); | |
| 2968 | + cstr_ccat(&tokcstr, '\0'); | |
| 2974 | 2969 | #ifdef PP_DEBUG |
| 2975 | − printf("\nstringize: <%s>\n", (char *)cstr.data); | |
| 2970 | + printf("\nstringize: <%s>\n", (char *)tokcstr.data); | |
| 2976 | 2971 | #endif |
| 2977 | 2972 | /* add string */ |
| 2978 | − cval.str.size = cstr.size; | |
| 2979 | − cval.str.data = cstr.data; | |
| 2973 | + cval.str.size = tokcstr.size; | |
| 2974 | + cval.str.data = tokcstr.data; | |
| 2980 | 2975 | tok_str_add2(&str, TOK_PPSTR, &cval); |
| 2981 | − cstr_free(&cstr); | |
| 2982 | 2976 | } else { |
| 2983 | 2977 | bad_stringy: |
| 2984 | 2978 | expect("macro parameter after '#'"); |
| @@ -3047,19 +3041,19 @@ static char const ab_month_name[12][4] = · 62 unmodified lines | ||
| 3047 | 3041 | |
| 3048 | 3042 | static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2) |
| 3049 | 3043 | { |
| 3050 | − CString cstr; | |
| 3051 | 3044 | int n, ret = 1; |
| 3052 | 3045 | |
| 3053 | − cstr_new(&cstr); | |
| 3046 | + cstr_reset(&tokcstr); | |
| 3054 | 3047 | if (t1 != TOK_PLCHLDR) |
| 3055 | − cstr_cat(&cstr, get_tok_str(t1, v1), -1); | |
| 3056 | − n = cstr.size; | |
| 3048 | + cstr_cat(&tokcstr, get_tok_str(t1, v1), -1); | |
| 3049 | + n = tokcstr.size; | |
| 3057 | 3050 | if (t2 != TOK_PLCHLDR) |
| 3058 | − cstr_cat(&cstr, get_tok_str(t2, v2), -1); | |
| 3059 | − cstr_ccat(&cstr, '\0'); | |
| 3051 | + cstr_cat(&tokcstr, get_tok_str(t2, v2), -1); | |
| 3052 | + cstr_ccat(&tokcstr, '\0'); | |
| 3053 | + //printf("paste <%s>\n", (char*)tokcstr.data); | |
| 3060 | 3054 | |
| 3061 | − tcc_open_bf(tcc_state, ":paste:", cstr.size); | |
| 3062 | − memcpy(file->buffer, cstr.data, cstr.size); | |
| 3055 | + tcc_open_bf(tcc_state, ":paste:", tokcstr.size); | |
| 3056 | + memcpy(file->buffer, tokcstr.data, tokcstr.size); | |
| 3063 | 3057 | tok_flags = 0; |
| 3064 | 3058 | for (;;) { |
| 3065 | 3059 | next_nomacro1(); |
| @@ -3068,13 +3062,11 @@ static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2) · 2 unmodified lines | ||
| 3068 | 3062 | if (is_space(tok)) |
| 3069 | 3063 | continue; |
| 3070 | 3064 | tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid" |
| 3071 | − " preprocessing token", n, (char *)cstr.data, (char*)cstr.data + n); | |
| 3065 | + " preprocessing token", n, file->buffer, file->buffer + n); | |
| 3072 | 3066 | ret = 0; |
| 3073 | 3067 | break; |
| 3074 | 3068 | } |
| 3075 | 3069 | tcc_close(); |
| 3076 | − //printf("paste <%s>\n", (char*)cstr.data); | |
| 3077 | − cstr_free(&cstr); | |
| 3078 | 3070 | return ret; |
| 3079 | 3071 | } |
| 3080 | 3072 | |
| @@ -3214,7 +3206,6 @@ static int macro_subst_tok( · 133 unmodified lines | ||
| 3214 | 3206 | TokenString str; |
| 3215 | 3207 | char *cstrval; |
| 3216 | 3208 | CValue cval; |
| 3217 | − CString cstr; | |
| 3218 | 3209 | char buf[32]; |
| 3219 | 3210 | |
| 3220 | 3211 | /* if symbol is a macro, prepare substitution */ |
| @@ -3245,12 +3236,11 @@ static int macro_subst_tok( · 24 unmodified lines | ||
| 3245 | 3236 | add_cstr: |
| 3246 | 3237 | t1 = TOK_STR; |
| 3247 | 3238 | add_cstr1: |
| 3248 | − cstr_new(&cstr); | |
| 3249 | − cstr_cat(&cstr, cstrval, 0); | |
| 3250 | − cval.str.size = cstr.size; | |
| 3251 | − cval.str.data = cstr.data; | |
| 3239 | + cstr_reset(&tokcstr); | |
| 3240 | + cstr_cat(&tokcstr, cstrval, 0); | |
| 3241 | + cval.str.size = tokcstr.size; | |
| 3242 | + cval.str.data = tokcstr.data; | |
| 3252 | 3243 | tok_str_add2(tok_str, t1, &cval); |
| 3253 | − cstr_free(&cstr); | |
| 3254 | 3244 | } else if (s->d) { |
| 3255 | 3245 | int saved_parse_flags = parse_flags; |
| 3256 | 3246 | int *joined_str = NULL; |
| @@ -3634,7 +3624,6 @@ static void tcc_predefs(TCCState *s1, CString *cs, int is_asm) · 377 unmodified lines | ||
| 3634 | 3624 | ST_FUNC void preprocess_start(TCCState *s1, int filetype) |
| 3635 | 3625 | { |
| 3636 | 3626 | int is_asm = !!(filetype & (AFF_TYPE_ASM|AFF_TYPE_ASMPP)); |
| 3637 | − CString cstr; | |
| 3638 | 3627 | |
| 3639 | 3628 | tccpp_new(s1); |
| 3640 | 3629 | |
| @@ -3652,6 +3641,7 @@ ST_FUNC void preprocess_start(TCCState *s1, int filetype) · 11 unmodified lines | ||
| 3652 | 3641 | set_idnum('.', is_asm ? IS_ID : 0); |
| 3653 | 3642 | |
| 3654 | 3643 | if (!(filetype & AFF_TYPE_ASM)) { |
| 3644 | + CString cstr; | |
| 3655 | 3645 | cstr_new(&cstr); |
| 3656 | 3646 | tcc_predefs(s1, &cstr, is_asm); |
| 3657 | 3647 | if (s1->cmdline_defs.size) |
| @@ -3710,6 +3700,7 @@ ST_FUNC void tccpp_new(TCCState *s) · 52 unmodified lines | ||
| 3710 | 3700 | memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *)); |
| 3711 | 3701 | memset(s->cached_includes_hash, 0, sizeof s->cached_includes_hash); |
| 3712 | 3702 | |
| 3703 | + cstr_new(&tokcstr); | |
| 3713 | 3704 | cstr_new(&cstr_buf); |
| 3714 | 3705 | cstr_realloc(&cstr_buf, STRING_MAX_SIZE); |
| 3715 | 3706 | tok_str_new(&tokstr_buf); |
| @@ -3755,7 +3746,6 @@ ST_FUNC void tccpp_delete(TCCState *s) · 39 unmodified lines | ||
| 3755 | 3746 | /* free static buffers */ |
| 3756 | 3747 | cstr_free(&tokcstr); |
| 3757 | 3748 | cstr_free(&cstr_buf); |
| 3758 | − cstr_free(¯o_equal_buf); | |
| 3759 | 3749 | tok_str_free_str(tokstr_buf.str); |
| 3760 | 3750 | |
| 3761 | 3751 | /* free allocators */ |