History

Fix preprocessor concat with empty arg

Thomas Preud'homme committed 12 years ago

Commit 6e56bb31 parent 9714d2e5 files · +56 −6Browse files

Unified · Split

5 files
  1. tcc.h +1 −0
  2. tccpp.c +37 −5
  3. tests/tests2/67_macro_concat.c +14 −0
  4. tests/tests2/67_macro_concat.expect +2 −0
  5. tests/tests2/Makefile +2 −1
tcc.h+1−0
@@ -836,6 +836,7 @@ struct TCCState { · 835 unmodified lines
836/* <-- */836/* <-- */
837 837
838#define TOK_TWOSHARPS 0xc0 /* ## preprocessing token */838#define TOK_TWOSHARPS 0xc0 /* ## preprocessing token */
839#define TOK_PLCHLDR 0xc1 /* placeholder token as defined in C99 */
839#define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */840#define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
840#define TOK_ADDC1 0xc3 /* add with carry generation */841#define TOK_ADDC1 0xc3 /* add with carry generation */
841#define TOK_ADDC2 0xc4 /* add with carry use */842#define TOK_ADDC2 0xc4 /* add with carry use */
tccpp.c+37−5
@@ -2565,7 +2565,8 @@ ST_FUNC void next_nomacro(void) · 2564 unmodified lines
2565 } while (is_space(tok));2565 } while (is_space(tok));
2566}2566}
2567 2567
2568/* substitute args in macro_str and return allocated string */2568/* substitute arguments in replacement lists in macro_str by the values in
2569 args (field d) and return allocated string */
2569static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)2570static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
2570{2571{
2571 int last_tok, t, spc;2572 int last_tok, t, spc;
@@ -2622,7 +2623,7 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 50 unmodified lines
2622 if (gnu_ext && s->type.t &&2623 if (gnu_ext && s->type.t &&
2623 last_tok == TOK_TWOSHARPS && 2624 last_tok == TOK_TWOSHARPS &&
2624 str.len >= 2 && str.str[str.len - 2] == ',') {2625 str.len >= 2 && str.str[str.len - 2] == ',') {
2625 if (*st == 0) {2626 if (*st == TOK_PLCHLDR) {
2626 /* suppress ',' '##' */2627 /* suppress ',' '##' */
2627 str.len -= 2;2628 str.len -= 2;
2628 } else {2629 } else {
@@ -2793,6 +2794,8 @@ static int macro_subst_tok(TokenString *tok_str, · 164 unmodified lines
2793 tok_str_add2(&str, tok, &tokc);2794 tok_str_add2(&str, tok, &tokc);
2794 next_nomacro_spc();2795 next_nomacro_spc();
2795 }2796 }
2797 if (!str.len)
2798 tok_str_add(&str, TOK_PLCHLDR);
2796 str.len -= spc;2799 str.len -= spc;
2797 tok_str_add(&str, 0);2800 tok_str_add(&str, 0);
2798 sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0);2801 sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0);
@@ -2885,9 +2888,11 @@ static inline int *macro_twosharps(const int *macro_str) · 86 unmodified lines
2885 TOK_GET(&t, &ptr, &cval);2888 TOK_GET(&t, &ptr, &cval);
2886 /* We concatenate the two tokens */2889 /* We concatenate the two tokens */
2887 cstr_new(&cstr);2890 cstr_new(&cstr);
2888 cstr_cat(&cstr, get_tok_str(tok, &tokc));2891 if (tok != TOK_PLCHLDR)
2892 cstr_cat(&cstr, get_tok_str(tok, &tokc));
2889 n = cstr.size;2893 n = cstr.size;
2890 cstr_cat(&cstr, get_tok_str(t, &cval));2894 if (t != TOK_PLCHLDR || tok == TOK_PLCHLDR)
2895 cstr_cat(&cstr, get_tok_str(t, &cval));
2891 cstr_ccat(&cstr, '\0');2896 cstr_ccat(&cstr, '\0');
2892 2897
2893 tcc_open_bf(tcc_state, ":paste:", cstr.size);2898 tcc_open_bf(tcc_state, ":paste:", cstr.size);
@@ -2904,8 +2909,35 @@ static inline int *macro_twosharps(const int *macro_str) · 10 unmodified lines
2904 cstr_free(&cstr);2909 cstr_free(&cstr);
2905 }2910 }
2906 }2911 }
2907 if (tok != TOK_NOSUBST) 2912 if (tok != TOK_NOSUBST) {
2913 const int *oldptr;
2914 CValue cval;
2915
2916 /* Check if a space need to be added after ## concatenation in
2917 order to avoid misinterpreting the newly formed token
2918 followed by the next token as being a single token (see
2919 macro_concat test) */
2920 cstr_new(&cstr);
2921 cstr_cat(&cstr, get_tok_str(tok, &tokc));
2922 oldptr = ptr;
2923 TOK_GET(&t, &ptr, &cval);
2924 ptr = oldptr;
2925 cstr_cat(&cstr, get_tok_str(t, &cval));
2926 cstr_ccat(&cstr, '\0');
2927 t = tok;
2928 cval = tokc;
2929 tcc_open_bf(tcc_state, ":paste:", cstr.size);
2930 memcpy(file->buffer, cstr.data, cstr.size);
2931 next_nomacro1();
2932 if (!*file->buf_ptr) {
2933 tok_str_add2(&macro_str1, t, &cval);
2934 tok = ' ';
2935 }
2936 tcc_close();
2937 cstr_free(&cstr);
2938
2908 start_of_nosubsts = -1;2939 start_of_nosubsts = -1;
2940 }
2909 tok_str_add2(&macro_str1, tok, &tokc);2941 tok_str_add2(&macro_str1, tok, &tokc);
2910 }2942 }
2911 tok_str_add(&macro_str1, 0);2943 tok_str_add(&macro_str1, 0);
tests/tests2/67_macro_concat.c+14−0
@@ -0,0 +1,14 @@
1#include <stdio.h>
2
3#define P(A,B) A ## B ; bob
4#define Q(A,B) A ## B+
5
6int main(void)
7{
8 int bob, jim = 21;
9 bob = P(jim,) *= 2;
10 printf("jim: %d, bob: %d\n", jim, bob);
11 jim = 60 Q(+,)3;
12 printf("jim: %d\n", jim);
13 return 0;
14}
tests/tests2/67_macro_concat.expect+2−0
@@ -0,0 +1,2 @@
1jim: 21, bob: 42
2jim: 63
tests/tests2/Makefile+2−1
@@ -81,7 +81,8 @@ TESTS = \ · 80 unmodified lines
81 63_local_enumerator_redefinition.test \81 63_local_enumerator_redefinition.test \
82 64_macro_nesting.test \82 64_macro_nesting.test \
83 65_macro_concat_start.test \83 65_macro_concat_start.test \
84 66_macro_concat_end.test84 66_macro_concat_end.test \
85 67_macro_concat.test
85 86
86# 30_hanoi.test -- seg fault in the code, gcc as well87# 30_hanoi.test -- seg fault in the code, gcc as well
87# 34_array_assignment.test -- array assignment is not in C standard88# 34_array_assignment.test -- array assignment is not in C standard

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