History

CStrings leakless

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

grischka committed 3 years ago

Commit a0454001 parent 40131b75 files · +118 −123Browse files

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t