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
899#define TOK_TWOSHARPS 0xca /* ## preprocessing token */899#define TOK_TWOSHARPS 0xca /* ## preprocessing token */
900#define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */900#define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */
901#define TOK_NOSUBST 0xcc /* means following token has already been pp'd */901#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 */
902 903
903#define TOK_SHL 0x01 /* shift left */904#define TOK_SHL 0x01 /* shift left */
904#define TOK_SAR 0x02 /* signed shift right */905#define TOK_SAR 0x02 /* signed shift right */
tccpp.c+8−7
@@ -1508,6 +1508,7 @@ ST_FUNC void parse_define(void) · 1507 unmodified lines
1508 if (1 == spc)1508 if (1 == spc)
1509 --tokstr_buf.len;1509 --tokstr_buf.len;
1510 spc = 3;1510 spc = 3;
1511 tok = TOK_PPJOIN;
1511 } else if ('#' == tok) {1512 } else if ('#' == tok) {
1512 spc = 4;1513 spc = 4;
1513 } else if (check_space(tok, &spc)) {1514 } 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
2958 int l0 = str.len;2959 int l0 = str.len;
2959 st = s->d;2960 st = s->d;
2960 /* if '##' is present before or after, no arg substitution */2961 /* 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) {
2962 /* special case for var arg macros : ## eats the ','2963 /* special case for var arg macros : ## eats the ','
2963 if empty VA_ARGS variable. */2964 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) {
2965 if (*st == 0) {2966 if (*st == 0) {
2966 /* suppress ',' '##' */2967 /* suppress ',' '##' */
2967 str.len -= 2;2968 str.len -= 2;
@@ -3277,7 +3278,7 @@ static inline int *macro_twosharps(const int *ptr0) · 309 unmodified lines
3277 /* we search the first '##' */3278 /* we search the first '##' */
3278 for (ptr = ptr0;;) {3279 for (ptr = ptr0;;) {
3279 TOK_GET(&t, &ptr, &cval);3280 TOK_GET(&t, &ptr, &cval);
3280 if (t == TOK_TWOSHARPS)3281 if (t == TOK_PPJOIN)
3281 break;3282 break;
3282 if (t == 0)3283 if (t == 0)
3283 return NULL;3284 return NULL;
@@ -3290,9 +3291,9 @@ static inline int *macro_twosharps(const int *ptr0) · 6 unmodified lines
3290 TOK_GET(&t, &ptr, &cval);3291 TOK_GET(&t, &ptr, &cval);
3291 if (t == 0)3292 if (t == 0)
3292 break;3293 break;
3293 if (t == TOK_TWOSHARPS)3294 if (t == TOK_PPJOIN)
3294 continue;3295 continue;
3295 while (*ptr == TOK_TWOSHARPS) {3296 while (*ptr == TOK_PPJOIN) {
3296 int t1; CValue cv1;3297 int t1; CValue cv1;
3297 /* given 'a##b', remove nosubsts preceding 'a' */3298 /* given 'a##b', remove nosubsts preceding 'a' */
3298 if (start_of_nosubsts >= 0)3299 if (start_of_nosubsts >= 0)
@@ -3300,7 +3301,7 @@ static inline int *macro_twosharps(const int *ptr0) · 1 unmodified line
3300 /* given 'a##b', remove nosubsts preceding 'b' */3301 /* given 'a##b', remove nosubsts preceding 'b' */
3301 while ((t1 = *++ptr) == TOK_NOSUBST)3302 while ((t1 = *++ptr) == TOK_NOSUBST)
3302 ;3303 ;
3303 if (t1 && t1 != TOK_TWOSHARPS) {3304 if (t1 && t1 != TOK_PPJOIN) {
3304 TOK_GET(&t1, &ptr, &cv1);3305 TOK_GET(&t1, &ptr, &cv1);
3305 if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) {3306 if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) {
3306 if (paste_tokens(t, &cval, t1, &cv1)) {3307 if (paste_tokens(t, &cval, t1, &cv1)) {
@@ -3346,7 +3347,7 @@ static void macro_subst( · 39 unmodified lines
3346 spc = nosubst = 0;3347 spc = nosubst = 0;
3347 3348
3348 /* first scan for '##' operator handling */3349 /* first scan for '##' operator handling */
3349 if (can_read_stream & 1) {3350 if (can_read_stream) {
3350 macro_str1 = macro_twosharps(ptr);3351 macro_str1 = macro_twosharps(ptr);
3351 if (macro_str1)3352 if (macro_str1)
3352 ptr = macro_str1;3353 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)
5X162 pass(__ASM_REG(tok))
6X161 pass(_ASM_DX)
7X163 pass(STR1(one##tok))
8
9X170 pass(x ## y)
10X171 pass(x pass(##) y)
11
12#define Y(x) Z(x)
13#define X Y
14X180 return X(X(1));
tests/pp/17.expect+6−0
@@ -0,0 +1,6 @@
1X162 "onetok"
2X161 "onetok"
3X163 "one##tok"
4X170 x ## y
5X171 x ## y
6X180 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