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
836836 /* <-- */
837837
838838 #define TOK_TWOSHARPS 0xc0 /* ## preprocessing token */
839+#define TOK_PLCHLDR 0xc1 /* placeholder token as defined in C99 */
839840 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
840841 #define TOK_ADDC1 0xc3 /* add with carry generation */
841842 #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
25652565 } while (is_space(tok));
25662566 }
25672567
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 */
25692570 static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
25702571 {
25712572 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
26222623 if (gnu_ext && s->type.t &&
26232624 last_tok == TOK_TWOSHARPS &&
26242625 str.len >= 2 && str.str[str.len - 2] == ',') {
2625− if (*st == 0) {
2626+ if (*st == TOK_PLCHLDR) {
26262627 /* suppress ',' '##' */
26272628 str.len -= 2;
26282629 } else {
@@ -2793,6 +2794,8 @@ static int macro_subst_tok(TokenString *tok_str, · 164 unmodified lines
27932794 tok_str_add2(&str, tok, &tokc);
27942795 next_nomacro_spc();
27952796 }
2797+ if (!str.len)
2798+ tok_str_add(&str, TOK_PLCHLDR);
27962799 str.len -= spc;
27972800 tok_str_add(&str, 0);
27982801 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
28852888 TOK_GET(&t, &ptr, &cval);
28862889 /* We concatenate the two tokens */
28872890 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));
28892893 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));
28912896 cstr_ccat(&cstr, '\0');
28922897
28932898 tcc_open_bf(tcc_state, ":paste:", cstr.size);
@@ -2904,8 +2909,35 @@ static inline int *macro_twosharps(const int *macro_str) · 10 unmodified lines
29042909 cstr_free(&cstr);
29052910 }
29062911 }
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+
29082939 start_of_nosubsts = -1;
2940+ }
29092941 tok_str_add2(&macro_str1, tok, &tokc);
29102942 }
29112943 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+
6+int 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 @@
1+jim: 21, bob: 42
2+jim: 63
tests/tests2/Makefile+2−1
@@ -81,7 +81,8 @@ TESTS = \ · 80 unmodified lines
8181 63_local_enumerator_redefinition.test \
8282 64_macro_nesting.test \
8383 65_macro_concat_start.test \
84− 66_macro_concat_end.test
84+ 66_macro_concat_end.test \
85+ 67_macro_concat.test
8586
8687 # 30_hanoi.test -- seg fault in the code, gcc as well
8788 # 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