diff options
author | zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-07-20 17:57:38 +0000 |
---|---|---|
committer | zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-07-20 17:57:38 +0000 |
commit | 356772305b57f73219333f38989e183eba455bdb (patch) | |
tree | 411ca2344aad9c248c5506109b46dc34a0f64bbf /gcc | |
parent | 92ac01460c75ee187f1fe74a74f88dbaaa2bd31a (diff) | |
download | gcc-356772305b57f73219333f38989e183eba455bdb.tar.gz |
* cppmacro.c (CAN_PASTE_AFTER): New macro.
(count_params): Don't set GNU_REST_ARGS on anything.
(save_expansion): Set PASTE_LEFT only on tokens for which
CAN_PASTE_AFTER is true, or which are named operators.
* cpplex.c (parse_args): Distinguish between a rest argument
given one empty argument, and a rest argument given zero arguments.
(maybe_paste_with_next): Look for VOID_REST tag, and trigger
deletion of previous token based on that.
(get_raw_token): Flatten some control structure.
* cpplib.h (CPP_LAST_EQ): Correct.
(VOID_REST): New token flag.
(GNU_REST_ARGS): Delete.
* gcc.dg/cpp/20000625-2.c, gcc.dg/cpp/macsyntx.c: Update error
regexps.
* gcc.dg/cpp/paste6.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35146 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 25 | ||||
-rw-r--r-- | gcc/cpplex.c | 44 | ||||
-rw-r--r-- | gcc/cpplib.h | 8 | ||||
-rw-r--r-- | gcc/cppmacro.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/20000625-2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/macsyntx.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/paste6.c | 12 |
8 files changed, 92 insertions, 40 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4c4138a6a81..af27727cad2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2000-07-20 Zack Weinberg <zack@wolery.cumb.org> + + * cppmacro.c (CAN_PASTE_AFTER): New macro. + (count_params): Don't set GNU_REST_ARGS on anything. + (save_expansion): Set PASTE_LEFT only on tokens for which + CAN_PASTE_AFTER is true, or which are named operators. + + * cpplex.c (parse_args): Distinguish between a rest argument + given one empty argument, and a rest argument given zero arguments. + (maybe_paste_with_next): Look for VOID_REST tag, and trigger + deletion of previous token based on that. + (get_raw_token): Flatten some control structure. + + * cpplib.h (CPP_LAST_EQ): Correct. + (VOID_REST): New token flag. + (GNU_REST_ARGS): Delete. + + * tradcpp.c (main): Don't munge -D options. + (make_definition): Bring -D handling in line with cpplib. + (do_define): Strip all leading whitespace from macro definitions. + +2000-07-20 David Billinghurst <David.Billinghurst@riotinto.com.au> + + * Makefile.in (tradcpp): Depend on intl.o and version.o. + 2000-07-20 Bruce Korb <bkorb@gnu.org> * fixincl/check.tpl: strip the platform specific types before testing diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 9c7a03c3e06..36beb95ed7d 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -2399,13 +2399,19 @@ parse_args (pfile, hp, args) debug("string"); This is exactly the same as if the rest argument had received no tokens - debug("string",); This extension is deprecated. */ - - if (argc + 1 == macro->paramc && (macro->flags & GNU_REST_ARGS)) + + if (argc + 1 == macro->paramc && (macro->flags & VAR_ARGS)) { /* Duplicate the placemarker. Then we can set its flags and position and safely be using more than one. */ - save_token (args, duplicate_token (pfile, &placemarker_token)); + cpp_token *pm = duplicate_token (pfile, &placemarker_token); + pm->flags = VOID_REST; + save_token (args, pm); args->ends[argc] = total + 1; + + if (CPP_OPTION (pfile, c99) && CPP_PEDANTIC (pfile)) + cpp_pedwarn (pfile, "ISO C99 requires rest arguments to be used"); + return 0; } else @@ -2710,17 +2716,11 @@ maybe_paste_with_next (pfile, token) pasted = duplicate_token (pfile, second); else if (second->type == CPP_PLACEMARKER) { - cpp_context *mac_context = CURRENT_CONTEXT (pfile) - 1; /* GCC has special extended semantics for a ## b where b is - a varargs parameter: a disappears if b consists of no - tokens. This extension is deprecated. */ - if ((mac_context->u.list->flags & GNU_REST_ARGS) - && (mac_context->u.list->tokens[mac_context->posn-1].val.aux + 1 - == (unsigned) mac_context->u.list->paramc)) - { - cpp_warning (pfile, "deprecated GNU ## extension used"); - pasted = duplicate_token (pfile, second); - } + a varargs parameter: a disappears if b was given no actual + arguments (not merely if b is an empty argument). */ + if (second->flags & VOID_REST) + pasted = duplicate_token (pfile, second); else pasted = duplicate_token (pfile, token); } @@ -3161,6 +3161,7 @@ get_raw_token (pfile) { result = context->pushed_token; context->pushed_token = 0; + return result; /* Cannot be a CPP_MACRO_ARG */ } else if (context->posn == context->count) { @@ -3168,21 +3169,19 @@ get_raw_token (pfile) return &eof_token; continue; } - else + else if (IS_ARG_CONTEXT (context)) { - if (IS_ARG_CONTEXT (context)) + result = context->u.arg[context->posn++]; + if (result == 0) { + context->flags ^= CONTEXT_RAW; result = context->u.arg[context->posn++]; - if (result == 0) - { - context->flags ^= CONTEXT_RAW; - result = context->u.arg[context->posn++]; - } - return result; /* Cannot be a CPP_MACRO_ARG */ } - result = &context->u.list->tokens[context->posn++]; + return result; /* Cannot be a CPP_MACRO_ARG */ } + result = &context->u.list->tokens[context->posn++]; + if (result->type != CPP_MACRO_ARG) return result; @@ -3225,7 +3224,6 @@ lex_next (pfile, clear) if (pfile->temp_used) release_temp_tokens (pfile); } - lex_line (pfile, list); pfile->contexts[0].count = list->tokens_used; diff --git a/gcc/cpplib.h b/gcc/cpplib.h index 4cec348811d..62755a9eb9b 100644 --- a/gcc/cpplib.h +++ b/gcc/cpplib.h @@ -46,7 +46,7 @@ typedef struct cpp_hashnode cpp_hashnode; the same order as their counterparts without the '=', like ">>". */ /* Positions in the table. */ -#define CPP_LAST_EQ CPP_LSHIFT +#define CPP_LAST_EQ CPP_MAX #define CPP_FIRST_DIGRAPH CPP_HASH #define TTYPE_TABLE \ @@ -154,7 +154,8 @@ struct cpp_string #define STRINGIFY_ARG (1 << 3) /* If macro argument to be stringified. */ #define PASTE_LEFT (1 << 4) /* If on LHS of a ## operator. */ #define PASTED (1 << 5) /* The result of a ## operator. */ -#define NAMED_OP (1 << 6) /* C++ named operators, also defined */ +#define NAMED_OP (1 << 6) /* C++ named operators, also "defined". */ +#define VOID_REST (1 << 7) /* When a rest arg gets zero actual args. */ /* A preprocessing token. This has been carefully packed and should occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */ @@ -178,8 +179,7 @@ struct cpp_token /* cpp_toklist flags. */ #define LIST_OFFSET (1 << 0) #define VAR_ARGS (1 << 1) -#define GNU_REST_ARGS (1 << 2) /* Set in addition to VAR_ARGS. */ -#define BEG_OF_FILE (1 << 3) +#define BEG_OF_FILE (1 << 2) struct directive; /* These are deliberately incomplete. */ struct answer; diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c index 3dc973f3b83..03a9a99659d 100644 --- a/gcc/cppmacro.c +++ b/gcc/cppmacro.c @@ -53,6 +53,14 @@ static unsigned int find_param PARAMS ((const cpp_token *, const cpp_token *)); static cpp_toklist * alloc_macro PARAMS ((cpp_reader *, struct macro_info *)); +/* These are all the tokens that can have something pasted after them. + Comma is included in the list only to support the GNU varargs extension + (where you write a ## b and a disappears if b is an empty rest argument). */ +#define CAN_PASTE_AFTER(type) \ +((type) <= CPP_LAST_EQ || (type) == CPP_COLON || (type) == CPP_HASH \ + || (type) == CPP_DEREF || (type) == CPP_DOT || (type) == CPP_NAME \ + || (type) == CPP_INT || (type) == CPP_FLOAT || (type) == CPP_NUMBER \ + || (type) == CPP_MACRO_ARG || (type) == CPP_PLACEMARKER || (type) == CPP_COMMA) /* Scans for a given token, returning the parameter number if found, or 0 if not found. Scans from FIRST to TOKEN - 1 or the first @@ -192,7 +200,6 @@ count_params (pfile, info) } else { - info->flags |= GNU_REST_ARGS; if (CPP_PEDANTIC (pfile)) cpp_pedwarn (pfile, "ISO C does not permit named varargs parameters"); @@ -294,9 +301,6 @@ parse_define (pfile, info) /* Constraint 6.10.3.5 */ if (!(info->flags & VAR_ARGS) && is__va_args__ (pfile, token)) return 1; - /* It might be worth doing a check here that we aren't a - macro argument, since we don't store the text of macro - arguments. This would reduce "len" and save space. */ } info->ntokens++; if (TOKEN_SPELL (token) == SPELL_STRING) @@ -463,7 +467,15 @@ save_expansion (pfile, info) continue; case CPP_PASTE: - dest[-1].flags |= PASTE_LEFT; + /* Set the paste flag on the token to our left, unless there + is no possible token to which it might be pasted. That + is critical for correct operation under some circumstances; + see gcc.dg/cpp/paste6.c. */ + if (CAN_PASTE_AFTER (dest[-1].type) || (dest[-1].flags & NAMED_OP)) + dest[-1].flags |= PASTE_LEFT; + else if (CPP_OPTION (pfile, warn_paste)) + cpp_warning_with_line (pfile, dest[-1].line, dest[-1].col, + "nothing can be pasted after this token"); continue; case CPP_HASH: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c9d7cf394c4..b093b20114b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2000-07-20 Zack Weinberg <zack@wolery.cumb.org> + + * gcc.dg/cpp/20000625-2.c, gcc.dg/cpp/macsyntx.c: Update error + regexps. + * gcc.dg/cpp/paste6.c: New test. + 2000-07-19 Zack Weinberg <zack@wolery.cumb.org> * gcc.dg/cpp/tr-direct.c: New test. diff --git a/gcc/testsuite/gcc.dg/cpp/20000625-2.c b/gcc/testsuite/gcc.dg/cpp/20000625-2.c index e0dd35c4595..437d8654f58 100644 --- a/gcc/testsuite/gcc.dg/cpp/20000625-2.c +++ b/gcc/testsuite/gcc.dg/cpp/20000625-2.c @@ -2,7 +2,7 @@ /* { dg-do run } */ #define symbol_version(name, version) name##@##version - +/* { dg-warning "nothing can be pasted" "" { target *-*-* } 4 } */ #define str(x) xstr(x) #define xstr(x) #x diff --git a/gcc/testsuite/gcc.dg/cpp/macsyntx.c b/gcc/testsuite/gcc.dg/cpp/macsyntx.c index 74b9403fc2b..c2746ee80c5 100644 --- a/gcc/testsuite/gcc.dg/cpp/macsyntx.c +++ b/gcc/testsuite/gcc.dg/cpp/macsyntx.c @@ -51,16 +51,15 @@ one(ichi\ two(ichi) /* { dg-error "not enough" } */ var0() /* OK. */ var0(ichi) /* OK. */ -var1() /* { dg-error "not enough" } */ -var1(ichi) /* { dg-error "not enough" } */ +var1() /* { dg-warning "rest arguments to be used" } */ +var1(ichi) /* { dg-warning "rest arguments to be used" } */ var1(ichi, ni) /* OK. */ -/* This tests two deprecated oddities of GNU rest args - omitting a - comma is OK, and backtracking a token on pasting an empty rest - args. */ +/* This tests two oddities of GNU rest args - omitting a comma is OK, + and backtracking a token on pasting an empty rest args. */ #define rest(x, y...) x ## y /* { dg-warning "ISO C" } */ -rest(ichi,) /* { dg-warning "deprecated" } */ -rest(ichi) /* { dg-warning "deprecated" } */ +rest(ichi,) /* OK. */ +rest(ichi) /* { dg-warning "rest arguments to be used" } */ #if 23 != rest(2, 3) /* OK, no warning. */ #error 23 != 23 !! #endif diff --git a/gcc/testsuite/gcc.dg/cpp/paste6.c b/gcc/testsuite/gcc.dg/cpp/paste6.c new file mode 100644 index 00000000000..0ac55df328a --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/paste6.c @@ -0,0 +1,12 @@ +/* Regression test for paste appearing at the beginning of a set of + actual arguments. Original bug exposed by Linux kernel. Problem + reported by Jakub Jelinek <jakub@redhat.com>. */ + +/* { dg-do compile } */ + +extern int foo(int x); + +#define bar(x) foo(x) +#define baz(x) bar(##x) /* { dg-warning "nothing can be pasted" } */ + +int quux(int y) { return baz(y); } |