Zack Weinberg wrote:- > This was reported to the Debian bug-tracking system: > > $ cat foo.c > _Pragma("foo"); int y; > #define FOO _Pragma("foo"); int x; > FOO > [EMAIL PROTECTED]:~$ cpp-3.2 foo.c > # 1 "foo.c" > # 1 "<built-in>" > # 1 "<command line>" > # 1 "foo.c" > > # 1 "foo.c" > #pragma foo > # 1 "foo.c" > ; int y; > > > # 3 "foo.c" > #pragma ; int x;foo > > > The first line is expanded correctly; the third is not (rendering > > _Pragma almost completely useless). > > Do you have time to look into this, Neil?
Fixed with a nasty kludge thus. We really should be leaving _Pragma as-is in preprocessed output IMO; (but processing it for pragmas handled by CPP itself) then this whole issue goes away, and so does the hoops I jump through to retain correct token line numbering. That's for 3.4. Bootstrapped and regtested; I'm going to put this in. Neil. * cpphash.h (FIRST, LAST, CUR, RLIMIT): Fix definitions. * cpplib.c (destringize_and_run): Kludge around getting tokens from in-progress macros. (_cpp_do__Pragma): Simplify. testsuite: * gcc.dg/cpp/_Pragma4.c: New test. Index: cpphash.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/cpphash.h,v retrieving revision 1.170 diff -u -p -r1.170 cpphash.h --- cpphash.h 12 Aug 2002 22:44:29 -0000 1.170 +++ cpphash.h 3 Sep 2002 21:51:47 -0000 @@ -166,10 +166,10 @@ struct tokenrun }; /* Accessor macros for struct cpp_context. */ -#define FIRST(c) (c->u.iso.first) -#define LAST(c) (c->u.iso.last) -#define CUR(c) (c->u.trad.cur) -#define RLIMIT(c) (c->u.trad.rlimit) +#define FIRST(c) ((c)->u.iso.first) +#define LAST(c) ((c)->u.iso.last) +#define CUR(c) ((c)->u.trad.cur) +#define RLIMIT(c) ((c)->u.trad.rlimit) typedef struct cpp_context cpp_context; struct cpp_context Index: cpplib.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cpplib.c,v retrieving revision 1.321 diff -u -p -r1.321 cpplib.c --- cpplib.c 14 Aug 2002 20:17:54 -0000 1.321 +++ cpplib.c 3 Sep 2002 21:51:47 -0000 @@ -1277,6 +1277,9 @@ destringize_and_run (pfile, in) { const unsigned char *src, *limit; char *dest, *result; + cpp_context saved_context; + cpp_context *saved_cur_context; + unsigned int saved_line; dest = result = alloca (in->len + 1); for (src = in->text, limit = src + in->len; src < limit;) @@ -1288,7 +1291,40 @@ destringize_and_run (pfile, in) } *dest = '\0'; + /* FIXME. All this saving is a horrible kludge to handle the case + when we're in a macro expansion. + + A better strategy it to not convert _Pragma to #pragma if doing + preprocessed output, but to just pass it through as-is, unless it + is a CPP pragma in which case is should be processed normally. + When compiling the preprocessed output the _Pragma should be + handled. This will be become necessary when we move to + line-at-a-time lexing since we will be macro-expanding the line + before outputting / compiling it. */ + saved_line = pfile->line; + saved_context = pfile->base_context; + saved_cur_context = pfile->context; + pfile->context = &pfile->base_context; run_directive (pfile, T_PRAGMA, result, dest - result); + pfile->context = saved_cur_context; + pfile->base_context = saved_context; + pfile->line = saved_line; + + /* See above comment. For the moment, we'd like + + token1 _Pragma ("foo") token2 + + to be output as + + token1 + # 7 "file.c" + #pragma foo + # 7 "file.c" + token2 + + Getting the line markers is a little tricky. */ + if (pfile->cb.line_change) + (*pfile->cb.line_change) (pfile, pfile->cur_token, false); } /* Handle the _Pragma operator. */ @@ -1298,26 +1334,11 @@ _cpp_do__Pragma (pfile) { const cpp_token *string = get__Pragma_string (pfile); - if (!string) + if (string) + destringize_and_run (pfile, &string->val.str); + else cpp_error (pfile, DL_ERROR, "_Pragma takes a parenthesized string literal"); - else - { - /* Ideally, we'd like - token1 _Pragma ("foo") token2 - to be output as - token1 - # 7 "file.c" - #pragma foo - # 7 "file.c" - token2 - Getting these correct line markers is a little tricky. */ - - unsigned int orig_line = pfile->line; - destringize_and_run (pfile, &string->val.str); - pfile->line = orig_line; - pfile->buffer->saved_flags = BOL; - } } /* Just ignore #sccs on all systems. */ Index: testsuite/gcc.dg/cpp/_Pragma4.c =================================================================== RCS file: testsuite/gcc.dg/cpp/_Pragma4.c diff -N testsuite/gcc.dg/cpp/_Pragma4.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gcc.dg/cpp/_Pragma4.c 3 Sep 2002 21:51:47 -0000 @@ -0,0 +1,12 @@ +/* { dg-do preprocess } */ + +/* Based on Debian GNATS PR 157416. 3 Sep 2002. */ + +#define b foo _Pragma ("bar") baz +a b c + +/* + { dg-final { if ![file exists _Pragma4.i] { return } } } + { dg-final { if { [grep _Pragma4.i "#pragma bat "] != "" } { return } } } + { dg-final { fail "_Pragma4.c: #pragma appearing on its own line" } } +*/