History

tccpp: Fix token pasting

See testcase. We must always paste tokens (at least if not currently substing a normal argument, which is a speed optimization only now) but at the same time must not regard a ## token coming from argument expansion as the token-paste operator, nor if we constructed a ## token due to pasting itself (that was already checked by pp/01.c).

Michael Matz committed 10 years ago

Commit 3e77bfb1 parent 3db03734 files · +29 −7Browse files

Unified · Split

4 files
  1. tcc.h +1 −0
  2. tccpp.c +8 −7
  3. tests/pp/17.c +14 −0
  4. tests/pp/17.expect +6 −0
tcc.h+1−0
@@ -899,6 +899,7 @@ struct filespec { · 898 unmodified lines
899899 #define TOK_TWOSHARPS 0xca /* ## preprocessing token */
900900 #define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */
901901 #define TOK_NOSUBST 0xcc /* means following token has already been pp'd */
902+#define TOK_PPJOIN 0xce /* A '##' in the right position to mean pasting */
902903
903904 #define TOK_SHL 0x01 /* shift left */
904905 #define TOK_SAR 0x02 /* signed shift right */
tccpp.c+8−7
@@ -1508,6 +1508,7 @@ ST_FUNC void parse_define(void) · 1507 unmodified lines
15081508 if (1 == spc)
15091509 --tokstr_buf.len;
15101510 spc = 3;
1511+ tok = TOK_PPJOIN;
15111512 } else if ('#' == tok) {
15121513 spc = 4;
15131514 } else if (check_space(tok, &spc)) {
@@ -2958,10 +2959,10 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 1444 unmodified lines
29582959 int l0 = str.len;
29592960 st = s->d;
29602961 /* if '##' is present before or after, no arg substitution */
2961− if (*macro_str == TOK_TWOSHARPS || t1 == TOK_TWOSHARPS) {
2962+ if (*macro_str == TOK_PPJOIN || t1 == TOK_PPJOIN) {
29622963 /* special case for var arg macros : ## eats the ','
29632964 if empty VA_ARGS variable. */
2964− if (t1 == TOK_TWOSHARPS && t0 == ',' && gnu_ext && s->type.t) {
2965+ if (t1 == TOK_PPJOIN && t0 == ',' && gnu_ext && s->type.t) {
29652966 if (*st == 0) {
29662967 /* suppress ',' '##' */
29672968 str.len -= 2;
@@ -3277,7 +3278,7 @@ static inline int *macro_twosharps(const int *ptr0) · 309 unmodified lines
32773278 /* we search the first '##' */
32783279 for (ptr = ptr0;;) {
32793280 TOK_GET(&t, &ptr, &cval);
3280− if (t == TOK_TWOSHARPS)
3281+ if (t == TOK_PPJOIN)
32813282 break;
32823283 if (t == 0)
32833284 return NULL;
@@ -3290,9 +3291,9 @@ static inline int *macro_twosharps(const int *ptr0) · 6 unmodified lines
32903291 TOK_GET(&t, &ptr, &cval);
32913292 if (t == 0)
32923293 break;
3293− if (t == TOK_TWOSHARPS)
3294+ if (t == TOK_PPJOIN)
32943295 continue;
3295− while (*ptr == TOK_TWOSHARPS) {
3296+ while (*ptr == TOK_PPJOIN) {
32963297 int t1; CValue cv1;
32973298 /* given 'a##b', remove nosubsts preceding 'a' */
32983299 if (start_of_nosubsts >= 0)
@@ -3300,7 +3301,7 @@ static inline int *macro_twosharps(const int *ptr0) · 1 unmodified line
33003301 /* given 'a##b', remove nosubsts preceding 'b' */
33013302 while ((t1 = *++ptr) == TOK_NOSUBST)
33023303 ;
3303− if (t1 && t1 != TOK_TWOSHARPS) {
3304+ if (t1 && t1 != TOK_PPJOIN) {
33043305 TOK_GET(&t1, &ptr, &cv1);
33053306 if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) {
33063307 if (paste_tokens(t, &cval, t1, &cv1)) {
@@ -3346,7 +3347,7 @@ static void macro_subst( · 39 unmodified lines
33463347 spc = nosubst = 0;
33473348
33483349 /* first scan for '##' operator handling */
3349− if (can_read_stream & 1) {
3350+ if (can_read_stream) {
33503351 macro_str1 = macro_twosharps(ptr);
33513352 if (macro_str1)
33523353 ptr = macro_str1;
tests/pp/17.c+14−0
@@ -0,0 +1,14 @@
1+#define STR1(u) # u
2+#define pass(a) a
3+#define __ASM_REG(reg) STR1(one##reg)
4+#define _ASM_DX __ASM_REG(tok)
5+X162 pass(__ASM_REG(tok))
6+X161 pass(_ASM_DX)
7+X163 pass(STR1(one##tok))
8+
9+X170 pass(x ## y)
10+X171 pass(x pass(##) y)
11+
12+#define Y(x) Z(x)
13+#define X Y
14+X180 return X(X(1));
tests/pp/17.expect+6−0
@@ -0,0 +1,6 @@
1+X162 "onetok"
2+X161 "onetok"
3+X163 "one##tok"
4+X170 x ## y
5+X171 x ## y
6+X180 return Z(Z(1));

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