forked from Mirrors/tinycc
tccpp: fix bug in handling of recursive macros
parent
cf08675702
commit
75c6695932
1
tcc.h
1
tcc.h
|
@ -683,6 +683,7 @@ struct TCCState {
|
||||||
#define TOK_DOTS 0xcc /* three dots */
|
#define TOK_DOTS 0xcc /* three dots */
|
||||||
#define TOK_SHR 0xcd /* unsigned shift right */
|
#define TOK_SHR 0xcd /* unsigned shift right */
|
||||||
#define TOK_PPNUM 0xce /* preprocessor number */
|
#define TOK_PPNUM 0xce /* preprocessor number */
|
||||||
|
#define TOK_NOSUBST 0xcf /* means following token has already been pp'd */
|
||||||
|
|
||||||
#define TOK_SHL 0x01 /* shift left */
|
#define TOK_SHL 0x01 /* shift left */
|
||||||
#define TOK_SAR 0x02 /* signed shift right */
|
#define TOK_SAR 0x02 /* signed shift right */
|
||||||
|
|
17
tccpp.c
17
tccpp.c
|
@ -2797,7 +2797,8 @@ static inline int *macro_twosharps(const int *macro_str)
|
||||||
if (tok == TOK_TWOSHARPS)
|
if (tok == TOK_TWOSHARPS)
|
||||||
continue;
|
continue;
|
||||||
while (*ptr == TOK_TWOSHARPS) {
|
while (*ptr == TOK_TWOSHARPS) {
|
||||||
t = *++ptr;
|
do { t = *++ptr; } while (t == TOK_NOSUBST);
|
||||||
|
|
||||||
if (t && t != TOK_TWOSHARPS) {
|
if (t && t != TOK_TWOSHARPS) {
|
||||||
TOK_GET(&t, &ptr, &cval);
|
TOK_GET(&t, &ptr, &cval);
|
||||||
|
|
||||||
|
@ -2856,11 +2857,20 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list,
|
||||||
TOK_GET(&t, &ptr, &cval);
|
TOK_GET(&t, &ptr, &cval);
|
||||||
if (t == 0)
|
if (t == 0)
|
||||||
break;
|
break;
|
||||||
|
if (t == TOK_NOSUBST) {
|
||||||
|
/* following token has already been subst'd. just copy it on */
|
||||||
|
tok_str_add2(tok_str, TOK_NOSUBST, NULL);
|
||||||
|
TOK_GET(&t, &ptr, &cval);
|
||||||
|
goto no_subst;
|
||||||
|
}
|
||||||
s = define_find(t);
|
s = define_find(t);
|
||||||
if (s != NULL) {
|
if (s != NULL) {
|
||||||
/* if nested substitution, do nothing */
|
/* if nested substitution, do nothing */
|
||||||
if (sym_find2(*nested_list, t))
|
if (sym_find2(*nested_list, t)) {
|
||||||
|
/* and mark it as TOK_NOSUBST, so it doesn't get subst'd again */
|
||||||
|
tok_str_add2(tok_str, TOK_NOSUBST, NULL);
|
||||||
goto no_subst;
|
goto no_subst;
|
||||||
|
}
|
||||||
ml.p = macro_ptr;
|
ml.p = macro_ptr;
|
||||||
if (can_read_stream)
|
if (can_read_stream)
|
||||||
ml.prev = *can_read_stream, *can_read_stream = &ml;
|
ml.prev = *can_read_stream, *can_read_stream = &ml;
|
||||||
|
@ -2928,6 +2938,9 @@ ST_FUNC void next(void)
|
||||||
macro_ptr = NULL;
|
macro_ptr = NULL;
|
||||||
}
|
}
|
||||||
goto redo;
|
goto redo;
|
||||||
|
} else if (tok == TOK_NOSUBST) {
|
||||||
|
/* discard preprocessor's nosubst markers */
|
||||||
|
goto redo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
void string_test();
|
void string_test();
|
||||||
void expr_test();
|
void expr_test();
|
||||||
void macro_test();
|
void macro_test();
|
||||||
|
void recursive_macro_test();
|
||||||
void scope_test();
|
void scope_test();
|
||||||
void forward_test();
|
void forward_test();
|
||||||
void funcptr_test();
|
void funcptr_test();
|
||||||
|
@ -281,6 +282,35 @@ comment
|
||||||
TEST2();
|
TEST2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void print_num(char *fn, int line, int num) {
|
||||||
|
printf("fn %s, line %d, num %d\n", fn, line, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
void recursive_macro_test(void)
|
||||||
|
{
|
||||||
|
#if 0 /* doesnt work yet */
|
||||||
|
#define ELF32_ST_TYPE(val) ((val) & 0xf)
|
||||||
|
#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
|
||||||
|
#define STB_WEAK 2 /* Weak symbol */
|
||||||
|
#define ELFW(type) ELF##32##_##type
|
||||||
|
printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123)));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define WRAP(x) x
|
||||||
|
|
||||||
|
#define print_num(x) print_num(__FILE__,__LINE__,x)
|
||||||
|
print_num(123);
|
||||||
|
WRAP(print_num(123));
|
||||||
|
WRAP(WRAP(print_num(123)));
|
||||||
|
|
||||||
|
static struct recursive_macro { int rm_field; } G;
|
||||||
|
#define rm_field (G.rm_field)
|
||||||
|
printf("rm_field = %d\n", rm_field);
|
||||||
|
printf("rm_field = %d\n", WRAP(rm_field));
|
||||||
|
WRAP((printf("rm_field = %d %d\n", rm_field, WRAP(rm_field))));
|
||||||
|
}
|
||||||
|
|
||||||
int op(a,b)
|
int op(a,b)
|
||||||
{
|
{
|
||||||
return a / b;
|
return a / b;
|
||||||
|
@ -501,6 +531,7 @@ int main(int argc, char **argv)
|
||||||
string_test();
|
string_test();
|
||||||
expr_test();
|
expr_test();
|
||||||
macro_test();
|
macro_test();
|
||||||
|
recursive_macro_test();
|
||||||
scope_test();
|
scope_test();
|
||||||
forward_test();
|
forward_test();
|
||||||
funcptr_test();
|
funcptr_test();
|
||||||
|
|
Loading…
Reference in New Issue