cpplex.c (parse_args): Don't set VOID_REST flag.
authorNeil Booth <neilb@earthling.net>
Mon, 25 Sep 2000 23:35:10 +0000 (23:35 +0000)
committerNeil Booth <neil@gcc.gnu.org>
Mon, 25 Sep 2000 23:35:10 +0000 (23:35 +0000)
        * cpplex.c (parse_args): Don't set VOID_REST flag.
(Fix diagnostic merge problem).
        (CONTEXT_VARARGS): New flag.
        (maybe_paste_with_next): Set context earlier in loop.  Use
        it.  Do varargs test with CONTEXT_VARARGS flag.
        (push_arg_context): Set CONTEXT_VARARGS flag if we're
        pushing an argument context for a varargs argument.
        * cpplib.h (VOID_REST): Delete.
        * gcc.dg/cpp/vararg1.c: Add test case.

From-SVN: r36638

gcc/ChangeLog
gcc/cpplex.c
gcc/cpplib.h
gcc/testsuite/gcc.dg/cpp/vararg1.c

index d2a5f1ed1b11a2726154b197cf7e11cf860d7164..3b3a6f2de3794a5094bec05c8b16f5d00c3fc576 100644 (file)
@@ -1,3 +1,14 @@
+Tue 26-Sep-2000 00:16:22 BST  Neil Booth  <neilb@earthling.net>
+
+        * cpplex.c (parse_args): Don't set VOID_REST flag.
+       (CONTEXT_VARARGS): New flag.
+       (maybe_paste_with_next): Set context earlier in loop.  Use
+       it.  Do varargs test with CONTEXT_VARARGS flag.
+       (push_arg_context): Set CONTEXT_VARARGS flag if we're
+       pushing an argument context for a varargs argument.
+       * cpplib.h (VOID_REST): Delete.
+       * gcc.dg/cpp/vararg1.c: Add test case.   
+
 2000-09-25  Branko Cibej  <branko.cibej@hermes.si>
 
         * flags.h:  Declare warning flag warn_system_headers.
index 47dcdbc3a84f0bcb51969394405065a654fa9374..4b2f84b03f85156e88dc1d337efed589316cc004 100644 (file)
@@ -52,6 +52,7 @@ static const cpp_token eof_token = {0, 0, CPP_EOF, 0 UNION_INIT_ZERO};
 #define CONTEXT_PASTER (1 << 1) /* An argument context on RHS of ##.  */
 #define CONTEXT_RAW    (1 << 2) /* If argument tokens already expanded.  */
 #define CONTEXT_ARG    (1 << 3) /* If an argument context.  */
+#define CONTEXT_VARARGS        (1 << 4) /* If a varargs argument context.  */
 
 typedef struct cpp_context cpp_context;
 struct cpp_context
@@ -1209,24 +1210,9 @@ lex_token (pfile, result)
             irrespective of conformance mode, because lots of
             broken systems do that and trying to clean it up in
             fixincludes is a nightmare.  */
-         if (CPP_OPTION (pfile, cplusplus_comments)
-             || CPP_IN_SYSTEM_HEADER (pfile))
+         if (CPP_OPTION (pfile, c89) && CPP_PEDANTIC (pfile)
+             && ! buffer->warned_cplusplus_comments)
            {
-             if (CPP_OPTION (pfile, c89) && CPP_PEDANTIC (pfile)
-                 && ! buffer->warned_cplusplus_comments)
-               {
-                 cpp_pedwarn (pfile,
-                      "C++ style comments are not allowed in ISO C89");
-                 cpp_pedwarn (pfile,
-                      "(this will be reported only once per input file)");
-                 buffer->warned_cplusplus_comments = 1;
-               }
-             comment_start = buffer->cur;
-
-             /* Skip_line_comment updates buffer->read_ahead.  */
-             if (skip_line_comment (pfile))
-               cpp_warning_with_line (pfile, result->line, result->col,
-                                      "multi-line comment");
              cpp_pedwarn (pfile,
                           "C++ style comments are not allowed in ISO C89");
              cpp_pedwarn (pfile,
@@ -1234,6 +1220,7 @@ lex_token (pfile, result)
              buffer->warned_cplusplus_comments = 1;
            }
 
+         /* Skip_line_comment updates buffer->read_ahead.  */
          if (skip_line_comment (pfile))
            cpp_warning_with_line (pfile, result->line, result->col,
                                   "multi-line comment");
@@ -2004,9 +1991,7 @@ parse_args (pfile, hp, args)
        {
          /* Duplicate the placemarker.  Then we can set its flags and
              position and safely be using more than one.  */
-         cpp_token *pm = duplicate_token (pfile, &placemarker_token);
-         pm->flags = VOID_REST;
-         save_token (args, pm);
+         save_token (args, duplicate_token (pfile, &placemarker_token));
          args->ends[argc] = total + 1;
 
          if (CPP_OPTION (pfile, c99) && CPP_PEDANTIC (pfile))
@@ -2316,6 +2301,7 @@ maybe_paste_with_next (pfile, token)
       pfile->paste_level = pfile->cur_context;
       second = _cpp_get_token (pfile);
       pfile->paste_level = 0;
+      context = CURRENT_CONTEXT (pfile);
 
       /* Ignore placemarker argument tokens (cannot be from an empty
         macro since macros are not expanded).  */
@@ -2327,7 +2313,7 @@ maybe_paste_with_next (pfile, token)
             a varargs parameter: the comma disappears if b was given
             no actual arguments (not merely if b is an empty
             argument).  */
-         if (token->type == CPP_COMMA && second->flags & VOID_REST)
+         if (token->type == CPP_COMMA && (context->flags & CONTEXT_VARARGS))
            pasted = duplicate_token (pfile, second);
          else
            pasted = duplicate_token (pfile, token);
@@ -2345,9 +2331,8 @@ maybe_paste_with_next (pfile, token)
                     <whatever> came from a variable argument, because
                     the author probably intended the ## to trigger
                     the special extended semantics (see above).  */
-                 if (token->type == CPP_COMMA
-                     && IS_ARG_CONTEXT (CURRENT_CONTEXT (pfile))
-                     && ON_REST_ARG (CURRENT_CONTEXT (pfile) - 1))
+                 if (token->type == CPP_COMMA && IS_ARG_CONTEXT (context)
+                     && ON_REST_ARG (context - 1))
                    /* no warning */;
                  else
                    cpp_warning (pfile,
@@ -2411,7 +2396,6 @@ maybe_paste_with_next (pfile, token)
       /* See if there is another token to be pasted onto the one we just
         constructed.  */
       token = pasted;
-      context = CURRENT_CONTEXT (pfile);
       /* and loop */
     }
   return token;
@@ -2592,6 +2576,9 @@ push_arg_context (pfile, token)
   context->posn = 0;
   context->level = args->level;
   context->flags = CONTEXT_ARG | CONTEXT_RAW;
+  if ((context[-1].u.list->flags & VAR_ARGS)
+      && token->val.aux + 1 == (unsigned) context[-1].u.list->paramc)
+    context->flags |= CONTEXT_VARARGS;
   context->pushed_token = 0;
 
   /* Set the flags of the first token.  There is one.  */
index 9b127136929f069fe0fbedce94fef22be95ea358..0f5235209f0cd3ef6cafb1047c7cf1bde9f23938 100644 (file)
@@ -160,7 +160,6 @@ struct cpp_string
 #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 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.  */
index aa8ed797318e52cbe550d8fdd0c5c770dcdb51e9..38bf56bd047ce45e50f76041347f10f96b71b2db 100644 (file)
@@ -1,11 +1,19 @@
+/* { dg-do run } */
+/* { dg-options -w } */
+
+/* count() used to give 1 owing to a buggy test for varargs.  */
+#define count(y...)  count1 ( , ##y)
+#define count1(y...) count2 (y,1,0)
+#define count2(_,x0,n,y...) n
+#if count() != 0 || count(A) != 1
+#error Incorrect vararg argument counts
+#endif
+
 /* Test for changed behavior of the GNU varargs extension.
    ##args, where args is a rest argument which received zero tokens,
    used to delete the previous sequence of nonwhitespace characters.
    Now it deletes the previous token.  */
 
-/* { dg-do run } */
-/* { dg-options -w } */
-
 #include <string.h>
 
 #define S(str, args...) "  " str "\n", ##args
@@ -16,4 +24,3 @@ main()
   const char *s = S("foo");
   return strchr (s, '\n') == NULL;
 }
-