OSDN Git Service

* cppmacro.c (CAN_PASTE_AFTER): New macro.
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 20 Jul 2000 17:57:38 +0000 (17:57 +0000)
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 20 Jul 2000 17:57:38 +0000 (17:57 +0000)
(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

gcc/ChangeLog
gcc/cpplex.c
gcc/cpplib.h
gcc/cppmacro.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/20000625-2.c
gcc/testsuite/gcc.dg/cpp/macsyntx.c
gcc/testsuite/gcc.dg/cpp/paste6.c [new file with mode: 0644]

index 4c4138a..af27727 100644 (file)
@@ -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
index 9c7a03c..36beb95 100644 (file)
@@ -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;
 
index 4cec348..62755a9 100644 (file)
@@ -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;
index 3dc973f..03a9a99 100644 (file)
@@ -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:
index c9d7cf3..b093b20 100644 (file)
@@ -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.
index e0dd35c..437d865 100644 (file)
@@ -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
 
index 74b9403..c2746ee 100644 (file)
@@ -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 (file)
index 0000000..0ac55df
--- /dev/null
@@ -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); }