summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2000-07-20 17:57:38 +0000
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2000-07-20 17:57:38 +0000
commit356772305b57f73219333f38989e183eba455bdb (patch)
tree411ca2344aad9c248c5506109b46dc34a0f64bbf /gcc
parent92ac01460c75ee187f1fe74a74f88dbaaa2bd31a (diff)
downloadgcc-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/ChangeLog25
-rw-r--r--gcc/cpplex.c44
-rw-r--r--gcc/cpplib.h8
-rw-r--r--gcc/cppmacro.c22
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/cpp/20000625-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/macsyntx.c13
-rw-r--r--gcc/testsuite/gcc.dg/cpp/paste6.c12
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); }