* cpplib.h (TTYPE_TABLE): Rearrange to use only two per-entry
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Jul 2000 23:25:06 +0000 (23:25 +0000)
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Jul 2000 23:25:06 +0000 (23:25 +0000)
          macros, not five.

* cpphash.h (TOKEN_NAME): New macro.
(_cpp_spell_operator): Deleted.
(token_spellings): Now _cpp_token_spellings.

* cppexp.c: Use TOKEN_NAME or TYPE_NAME, not _cpp_spell_operator.
* cpplex.c: Use OP and TK macros when expanding the
TTYPE_TABLE.  Eliminate token_names.  For non-OPERATOR tokens,
store the stringification of the enumeration name (CPP_CHAR,
etc.) in the name slot of token_spellings.
Use TOKEN_NAME and/or TOKEN_SPELL, do not reference
token_spellings directly.
* cpplib.c: Use TOKEN_SPELL.

* cpplex.c (_cpp_push_token): If the token being pushed back
is the previous token in this context, just subtract one from
context->posn.
* cppmacro.c (save_expansion): Clear aux field when storing a
placemarker.

* gcc.dg/cpp/paste5.c: New test.
* gcc.dg/cpp/vararg1.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35124 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cppexp.c
gcc/cpphash.h
gcc/cpplex.c
gcc/cpplib.c
gcc/cpplib.h
gcc/cppmacro.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/paste5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/vararg1.c [new file with mode: 0644]

index 6eb54bf..b6d3f22 100644 (file)
@@ -1,3 +1,27 @@
+2000-07-18  Zack Weinberg  <zack@wolery.cumb.org>
+
+       * cpplib.h (TTYPE_TABLE): Rearrange to use only two per-entry
+          macros, not five.
+
+       * cpphash.h (TOKEN_NAME): New macro.
+       (_cpp_spell_operator): Deleted.
+       (token_spellings): Now _cpp_token_spellings.
+
+       * cppexp.c: Use TOKEN_NAME or TYPE_NAME, not _cpp_spell_operator.
+       * cpplex.c: Use OP and TK macros when expanding the
+       TTYPE_TABLE.  Eliminate token_names.  For non-OPERATOR tokens,
+       store the stringification of the enumeration name (CPP_CHAR,
+       etc.) in the name slot of token_spellings.
+       Use TOKEN_NAME and/or TOKEN_SPELL, do not reference
+       token_spellings directly.
+       * cpplib.c: Use TOKEN_SPELL.
+       
+       * cpplex.c (_cpp_push_token): If the token being pushed back
+       is the previous token in this context, just subtract one from
+       context->posn.
+       * cppmacro.c (save_expansion): Clear aux field when storing a
+       placemarker.
+
 2000-07-18  Jakub Jelinek  <jakub@redhat.com>
 
        * cpplex.c (cpp_scan_buffer): Output line command even at the stop
index ce1d82b..deb5ffb 100644 (file)
@@ -397,7 +397,6 @@ lex (pfile, skip_evaluation)
   switch (tok->type)
     {
     case CPP_PLACEMARKER:
-      /* XXX These shouldn't be visible outside cpplex.c.  */
       goto retry;
 
     case CPP_INT:
@@ -443,8 +442,7 @@ lex (pfile, skip_evaluation)
          return op;
        }
 
-      SYNTAX_ERROR2("'%s' is not valid in #if expressions",
-                   _cpp_spell_operator (tok->type));
+      SYNTAX_ERROR2("'%s' is not valid in #if expressions", TOKEN_NAME (tok));
   }
 
  syntax_error:
@@ -718,6 +716,8 @@ op_to_prio[] =
 /* Parse and evaluate a C expression, reading from PFILE.
    Returns the truth value of the expression.  */
 
+#define TYPE_NAME(t) _cpp_token_spellings[t].name
+
 int
 _cpp_parse_expr (pfile)
      cpp_reader *pfile;
@@ -804,7 +804,7 @@ _cpp_parse_expr (pfile)
                SYNTAX_ERROR ("void expression between '(' and ')'");
              else
                SYNTAX_ERROR2 ("operator '%s' has no right operand",
-                              _cpp_spell_operator (top->op));
+                              TYPE_NAME (top->op));
            }
 
          unsigned2 = top->unsignedp, v2 = top->value;
@@ -815,8 +815,7 @@ _cpp_parse_expr (pfile)
          switch (top[1].op)
            {
            default:
-             cpp_ice (pfile, "impossible operator type %s",
-                      _cpp_spell_operator (op.op));
+             cpp_ice (pfile, "impossible operator type %s", TYPE_NAME (op.op));
              goto syntax_error;
 
            case CPP_NOT:        UNARY(!);      break;
@@ -969,13 +968,13 @@ _cpp_parse_expr (pfile)
        {
          if (top->flags & HAVE_VALUE)
            SYNTAX_ERROR2 ("missing binary operator before '%s'",
-                          _cpp_spell_operator (op.op));
+                          TYPE_NAME (op.op));
        }
       else
        {
          if (!(top->flags & HAVE_VALUE))
            SYNTAX_ERROR2 ("operator '%s' has no left operand",
-                          _cpp_spell_operator (op.op));
+                          TYPE_NAME (op.op));
        }
 
       /* Check for and handle stack overflow.  */
index 98fcbb6..51f7787 100644 (file)
@@ -38,12 +38,13 @@ enum spell_type
 
 struct token_spelling
 {
-  ENUM_BITFIELD(spell_type) type : CHAR_BIT;
-  const U_CHAR *spelling;
+  enum spell_type category;
+  const U_CHAR *name;
 };
 
-extern const struct token_spelling token_spellings[];
-#define TOKEN_SPELL(token) (token_spellings[(token)->type].type)
+extern const struct token_spelling _cpp_token_spellings[];
+#define TOKEN_SPELL(token) (_cpp_token_spellings[(token)->type].category)
+#define TOKEN_NAME(token) (_cpp_token_spellings[(token)->type].name)
 
 /* Chained list of answers to an assertion.  */
 struct answer
@@ -267,7 +268,6 @@ extern const cpp_token *_cpp_get_token PARAMS ((cpp_reader *));
 extern const cpp_token *_cpp_get_raw_token PARAMS ((cpp_reader *));
 extern void _cpp_push_token PARAMS ((cpp_reader *, const cpp_token*));
 extern const cpp_token *_cpp_glue_header_name PARAMS ((cpp_reader *));
-extern const U_CHAR *_cpp_spell_operator PARAMS ((enum cpp_ttype));
 
 /* In cpplib.c */
 extern const struct directive *_cpp_check_directive
index 0d5ef46..d0d76f9 100644 (file)
@@ -209,35 +209,14 @@ static void process_directive PARAMS ((cpp_reader *, const cpp_token *));
       if ((f) & BOL) {(d)->col = (s)->col; (d)->line = (s)->line;} \
   } while (0)
 
-#define T(e, s) {SPELL_OPERATOR, (const U_CHAR *) s},
-#define I(e, s) {SPELL_IDENT, s},
-#define S(e, s) {SPELL_STRING, s},
-#define C(e, s) {SPELL_CHAR, s},
-#define N(e, s) {SPELL_NONE, s},
+#define OP(e, s) { SPELL_OPERATOR, U s           },
+#define TK(e, s) { s,              U STRINGX (e) },
 
 const struct token_spelling
-token_spellings [N_TTYPES + 1] = {TTYPE_TABLE {0, 0} };
+_cpp_token_spellings [N_TTYPES] = {TTYPE_TABLE };
 
-#undef T
-#undef I
-#undef S
-#undef C
-#undef N
-
-/* For debugging: the internal names of the tokens.  */
-#define T(e, s) U STRINGX(e),
-#define I(e, s) U STRINGX(e),
-#define S(e, s) U STRINGX(e),
-#define C(e, s) U STRINGX(e),
-#define N(e, s) U STRINGX(e),
-
-const U_CHAR *const token_names[N_TTYPES] = { TTYPE_TABLE };
-
-#undef T
-#undef I
-#undef S
-#undef C
-#undef N
+#undef OP
+#undef TK
 
 /* The following table is used by trigraph_ok/trigraph_replace.  If we
    have designated initializers, it can be constant data; otherwise,
@@ -579,7 +558,7 @@ _cpp_expand_name_space (list, len)
       unsigned int i;
 
       for (i = 0; i < list->tokens_used; i++)
-       if (token_spellings[list->tokens[i].type].type == SPELL_STRING)
+       if (TOKEN_SPELL (&list->tokens[i]) == SPELL_STRING)
          list->tokens[i].val.str.text += (list->namebuf - old_namebuf);
     }
 }
@@ -684,7 +663,7 @@ _cpp_equiv_tokens (a, b)
      const cpp_token *a, *b;
 {
   if (a->type == b->type && a->flags == b->flags)
-    switch (token_spellings[a->type].type)
+    switch (TOKEN_SPELL (a))
       {
       default:                 /* Keep compiler happy.  */
       case SPELL_OPERATOR:
@@ -1966,7 +1945,7 @@ spell_token (pfile, token, buffer)
      const cpp_token *token;
      unsigned char *buffer;
 {
-  switch (token_spellings[token->type].type)
+  switch (TOKEN_SPELL (token))
     {
     case SPELL_OPERATOR:
       {
@@ -1976,7 +1955,7 @@ spell_token (pfile, token, buffer)
        if (token->flags & DIGRAPH)
          spelling = digraph_spellings[token->type - CPP_FIRST_DIGRAPH];
        else
-         spelling = token_spellings[token->type].spelling;
+         spelling = TOKEN_NAME (token);
        
        while ((c = *spelling++) != '\0')
          *buffer++ = c;
@@ -2013,26 +1992,13 @@ spell_token (pfile, token, buffer)
       break;
 
     case SPELL_NONE:
-      cpp_ice (pfile, "Unspellable token %s", token_names[token->type]);
+      cpp_ice (pfile, "Unspellable token %s", TOKEN_NAME (token));
       break;
     }
 
   return buffer;
 }
 
-/* Return the spelling of a token known to be an operator.
-   Does not distinguish digraphs from their counterparts.  */
-const unsigned char *
-_cpp_spell_operator (type)
-     enum cpp_ttype type;
-{
-  if (token_spellings[type].type == SPELL_OPERATOR)
-    return token_spellings[type].spelling;
-  else
-    return token_names[type];
-}
-
-
 /* Macro expansion algorithm.
 
 Macro expansion is implemented by a single-pass algorithm; there are
@@ -2554,7 +2520,7 @@ release_temp_tokens (pfile)
     {
       cpp_token *token = pfile->temp_tokens[--pfile->temp_used];
 
-      if (token_spellings[token->type].type == SPELL_STRING)
+      if (TOKEN_SPELL (token) == SPELL_STRING)
        {
          free ((char *) token->val.str.text);
          token->val.str.text = 0;
@@ -2595,7 +2561,7 @@ duplicate_token (pfile, token)
   cpp_token *result = get_temp_token (pfile);
 
   *result = *token;
-  if (token_spellings[token->type].type == SPELL_STRING)
+  if (TOKEN_SPELL (token) == SPELL_STRING)
     {
       U_CHAR *buff = (U_CHAR *) xmalloc (token->val.str.len);
       memcpy (buff, token->val.str.text, token->val.str.len);
@@ -2837,6 +2803,9 @@ stringify_arg (pfile, token)
       unsigned char *buf;
       unsigned int len = TOKEN_LEN (token);
 
+      if (token->type == CPP_PLACEMARKER)
+       continue;
+
       escape = (token->type == CPP_STRING || token->type == CPP_WSTRING
                || token->type == CPP_CHAR || token->type == CPP_WCHAR);
       if (escape)
@@ -3008,6 +2977,22 @@ _cpp_push_token (pfile, token)
      const cpp_token *token;
 {
   cpp_context *context = CURRENT_CONTEXT (pfile);
+
+  if (context->posn > 0)
+    {
+      const cpp_token *prev;
+      if (IS_ARG_CONTEXT (context))
+       prev = context->u.arg[context->posn - 1];
+      else
+       prev = &context->u.list->tokens[context->posn - 1];
+
+      if (prev == token)
+       {
+         context->posn--;
+         return;
+       }
+    }
+
   if (context->pushed_token)
     cpp_ice (pfile, "two tokens pushed in a row");
   if (token->type != CPP_EOF)
@@ -3031,8 +3016,7 @@ process_directive (pfile, token)
   if (token[1].type == CPP_NAME)
     _cpp_get_raw_token (pfile);
   else if (token[1].type != CPP_NUMBER)
-    cpp_ice (pfile, "directive begins with %s?!",
-            token_names[token[1].type]);
+    cpp_ice (pfile, "directive begins with %s?!", TOKEN_NAME (token));
 
   /* Flush pending tokens at this point, in case the directive produces
      output.  XXX Directive output won't be visible to a direct caller of
@@ -3491,7 +3475,7 @@ _cpp_dump_list (pfile, list, token, flush)
            CPP_PUTC (pfile, '#');
          dump_param_spelling (pfile, list, token->val.aux);
        }
-      else
+      else if (token->type != CPP_PLACEMARKER)
        output_token (pfile, token, prev);
       if (token->flags & PASTE_LEFT)
        CPP_PUTS (pfile, " ##", 3);
index adbd8d1..520821a 100644 (file)
@@ -1252,7 +1252,7 @@ _cpp_parse_assertion (pfile, answerp)
       dest = &list->tokens[list->tokens_used++];
       *dest = *token;
 
-      if (token_spellings[token->type].type == SPELL_STRING)
+      if (TOKEN_SPELL (token) == SPELL_STRING)
        {
          _cpp_expand_name_space (list, token->val.str.len);
          dest->val.str.text = list->namebuf + list->name_used;
index 80671cf..b8da90a 100644 (file)
@@ -50,96 +50,92 @@ typedef struct cpp_hashnode cpp_hashnode;
 #define CPP_FIRST_DIGRAPH CPP_HASH
 
 #define TTYPE_TABLE                            \
-  T(CPP_EQ = 0,                "=")                    \
-  T(CPP_NOT,           "!")                    \
-  T(CPP_GREATER,       ">")    /* compare */   \
-  T(CPP_LESS,          "<")                    \
-  T(CPP_PLUS,          "+")    /* math */      \
-  T(CPP_MINUS,         "-")                    \
-  T(CPP_MULT,          "*")                    \
-  T(CPP_DIV,           "/")                    \
-  T(CPP_MOD,           "%")                    \
-  T(CPP_AND,           "&")    /* bit ops */   \
-  T(CPP_OR,            "|")                    \
-  T(CPP_XOR,           "^")                    \
-  T(CPP_RSHIFT,                ">>")                   \
-  T(CPP_LSHIFT,                "<<")                   \
+  OP(CPP_EQ = 0,       "=")                    \
+  OP(CPP_NOT,          "!")                    \
+  OP(CPP_GREATER,      ">")    /* compare */   \
+  OP(CPP_LESS,         "<")                    \
+  OP(CPP_PLUS,         "+")    /* math */      \
+  OP(CPP_MINUS,                "-")                    \
+  OP(CPP_MULT,         "*")                    \
+  OP(CPP_DIV,          "/")                    \
+  OP(CPP_MOD,          "%")                    \
+  OP(CPP_AND,          "&")    /* bit ops */   \
+  OP(CPP_OR,           "|")                    \
+  OP(CPP_XOR,          "^")                    \
+  OP(CPP_RSHIFT,       ">>")                   \
+  OP(CPP_LSHIFT,       "<<")                   \
 \
-  T(CPP_COMPL,         "~")                    \
-  T(CPP_AND_AND,       "&&")   /* logical */   \
-  T(CPP_OR_OR,         "||")                   \
-  T(CPP_QUERY,         "?")                    \
-  T(CPP_COLON,         ":")                    \
-  T(CPP_COMMA,         ",")    /* grouping */  \
-  T(CPP_OPEN_PAREN,    "(")                    \
-  T(CPP_CLOSE_PAREN,   ")")                    \
-  T(CPP_EQ_EQ,         "==")   /* compare */   \
-  T(CPP_NOT_EQ,                "!=")                   \
-  T(CPP_GREATER_EQ,    ">=")                   \
-  T(CPP_LESS_EQ,       "<=")                   \
+  OP(CPP_COMPL,                "~")                    \
+  OP(CPP_AND_AND,      "&&")   /* logical */   \
+  OP(CPP_OR_OR,                "||")                   \
+  OP(CPP_QUERY,                "?")                    \
+  OP(CPP_COLON,                ":")                    \
+  OP(CPP_COMMA,                ",")    /* grouping */  \
+  OP(CPP_OPEN_PAREN,   "(")                    \
+  OP(CPP_CLOSE_PAREN,  ")")                    \
+  OP(CPP_EQ_EQ,                "==")   /* compare */   \
+  OP(CPP_NOT_EQ,       "!=")                   \
+  OP(CPP_GREATER_EQ,   ">=")                   \
+  OP(CPP_LESS_EQ,      "<=")                   \
 \
-  T(CPP_PLUS_EQ,       "+=")   /* math */      \
-  T(CPP_MINUS_EQ,      "-=")                   \
-  T(CPP_MULT_EQ,       "*=")                   \
-  T(CPP_DIV_EQ,                "/=")                   \
-  T(CPP_MOD_EQ,                "%=")                   \
-  T(CPP_AND_EQ,                "&=")   /* bit ops */   \
-  T(CPP_OR_EQ,         "|=")                   \
-  T(CPP_XOR_EQ,                "^=")                   \
-  T(CPP_RSHIFT_EQ,     ">>=")                  \
-  T(CPP_LSHIFT_EQ,     "<<=")                  \
+  OP(CPP_PLUS_EQ,      "+=")   /* math */      \
+  OP(CPP_MINUS_EQ,     "-=")                   \
+  OP(CPP_MULT_EQ,      "*=")                   \
+  OP(CPP_DIV_EQ,       "/=")                   \
+  OP(CPP_MOD_EQ,       "%=")                   \
+  OP(CPP_AND_EQ,       "&=")   /* bit ops */   \
+  OP(CPP_OR_EQ,                "|=")                   \
+  OP(CPP_XOR_EQ,       "^=")                   \
+  OP(CPP_RSHIFT_EQ,    ">>=")                  \
+  OP(CPP_LSHIFT_EQ,    "<<=")                  \
   /* Digraphs together, beginning with CPP_FIRST_DIGRAPH.  */  \
-  T(CPP_HASH,          "#")    /* digraphs */  \
-  T(CPP_PASTE,         "##")                   \
-  T(CPP_OPEN_SQUARE,   "[")                    \
-  T(CPP_CLOSE_SQUARE,  "]")                    \
-  T(CPP_OPEN_BRACE,    "{")                    \
-  T(CPP_CLOSE_BRACE,   "}")                    \
-  /* The remainder of the punctuation.  Order is not significant. */   \
-  T(CPP_SEMICOLON,     ";")    /* structure */ \
-  T(CPP_ELLIPSIS,      "...")                  \
-  T(CPP_BACKSLASH,     "\\")                   \
-  T(CPP_PLUS_PLUS,     "++")   /* increment */ \
-  T(CPP_MINUS_MINUS,   "--")                   \
-  T(CPP_DEREF,         "->")   /* accessors */ \
-  T(CPP_DOT,           ".")                    \
-  T(CPP_SCOPE,         "::")                   \
-  T(CPP_DEREF_STAR,    "->*")                  \
-  T(CPP_DOT_STAR,      ".*")                   \
-  T(CPP_MIN,           "<?")   /* extension */ \
-  T(CPP_MAX,           ">?")                   \
-  T(CPP_PLACEMARKER,   "")     /* Placemarker token.  */  \
-  C(CPP_OTHER,         0)      /* stray punctuation */    \
+  OP(CPP_HASH,         "#")    /* digraphs */  \
+  OP(CPP_PASTE,                "##")                   \
+  OP(CPP_OPEN_SQUARE,  "[")                    \
+  OP(CPP_CLOSE_SQUARE, "]")                    \
+  OP(CPP_OPEN_BRACE,   "{")                    \
+  OP(CPP_CLOSE_BRACE,  "}")                    \
+  /* The remainder of the punctuation.  Order is not significant.  */  \
+  OP(CPP_SEMICOLON,    ";")    /* structure */ \
+  OP(CPP_ELLIPSIS,     "...")                  \
+  OP(CPP_BACKSLASH,    "\\")                   \
+  OP(CPP_PLUS_PLUS,    "++")   /* increment */ \
+  OP(CPP_MINUS_MINUS,  "--")                   \
+  OP(CPP_DEREF,                "->")   /* accessors */ \
+  OP(CPP_DOT,          ".")                    \
+  OP(CPP_SCOPE,                "::")                   \
+  OP(CPP_DEREF_STAR,   "->*")                  \
+  OP(CPP_DOT_STAR,     ".*")                   \
+  OP(CPP_MIN,          "<?")   /* extension */ \
+  OP(CPP_MAX,          ">?")                   \
 \
-  I(CPP_NAME,          0)      /* word */      \
-  S(CPP_INT,           0)      /* 23 */        \
-  S(CPP_FLOAT,         0)      /* 3.14159 */   \
-  S(CPP_NUMBER,                0)      /* 34_be+ta  */ \
-  S(CPP_CHAR,          0)      /* 'char' */    \
-  S(CPP_WCHAR,         0)      /* L'char' */   \
-  S(CPP_STRING,                0)      /* "string" */  \
-  S(CPP_WSTRING,       0)      /* L"string" */ \
+  TK(CPP_NAME,         SPELL_IDENT)    /* word */                      \
+  TK(CPP_INT,          SPELL_STRING)   /* 23 */                        \
+  TK(CPP_FLOAT,                SPELL_STRING)   /* 3.14159 */                   \
+  TK(CPP_NUMBER,       SPELL_STRING)   /* 34_be+ta  */                 \
 \
-  S(CPP_COMMENT,       0)      /* Only if output comments.  */ \
-  N(CPP_MACRO_ARG,      0)     /* Macro argument.  */          \
-  N(CPP_EOF,           0)      /* End of file.  */             \
-  S(CPP_HEADER_NAME,   0)      /* <stdio.h> in #include */
-
-#define T(e, s) e,
-#define I(e, s) e,
-#define S(e, s) e,
-#define C(e, s) e,
-#define N(e, s) e,
+  TK(CPP_CHAR,         SPELL_STRING)   /* 'char' */                    \
+  TK(CPP_WCHAR,                SPELL_STRING)   /* L'char' */                   \
+  TK(CPP_OTHER,                SPELL_CHAR)     /* stray punctuation */         \
+\
+  TK(CPP_STRING,       SPELL_STRING)   /* "string" */                  \
+  TK(CPP_WSTRING,      SPELL_STRING)   /* L"string" */                 \
+  TK(CPP_HEADER_NAME,  SPELL_STRING)   /* <stdio.h> in #include */     \
+\
+  TK(CPP_COMMENT,      SPELL_STRING)   /* Only if output comments.  */ \
+  TK(CPP_MACRO_ARG,    SPELL_NONE)     /* Macro argument.  */          \
+  TK(CPP_PLACEMARKER,  SPELL_NONE)     /* Placemarker token.  */       \
+  TK(CPP_EOF,          SPELL_NONE)     /* End of file.  */
+
+#define OP(e, s) e,
+#define TK(e, s) e,
 enum cpp_ttype
 {
   TTYPE_TABLE
   N_TTYPES
 };
-#undef T
-#undef I
-#undef S
-#undef C
-#undef N
+#undef OP
+#undef TK
 
 /* Payload of a NUMBER, FLOAT, STRING, or COMMENT token.  */
 struct cpp_string
index 710dbde..3dc973f 100644 (file)
@@ -495,6 +495,7 @@ save_expansion (pfile, info)
     {
       dest->type = CPP_PLACEMARKER;
       dest->flags = 0;
+      dest->val.aux = 0;
     }
 
   return list;
index af08f07..2ed6ef1 100644 (file)
@@ -1,3 +1,11 @@
+2000-07-18  Zack Weinberg  <zack@wolery.cumb.org>
+
+       * cpplex.c (_cpp_push_token): If the token being pushed back
+       is the previous token in this context, just subtract one from
+       context->posn.
+       * cppmacro.c (save_expansion): Clear aux field when storing a
+       placemarker.
+
 2000-07-18  Alexandre Oliva  <aoliva@redhat.com>
 
        * gcc.dg/noncompile/redecl-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/cpp/paste5.c b/gcc/testsuite/gcc.dg/cpp/paste5.c
new file mode 100644 (file)
index 0000000..2a763f5
--- /dev/null
@@ -0,0 +1,24 @@
+/* Regression test for bug in convoluted situation involving token paste
+   plus function-like macros used outside function context.  It may be
+   easier to understand if you mentally replace 'struct' with 'A'
+   throughout this file; 'struct' is used only to get the code to compile
+   when preprocessed correctly.
+
+   The original problem was seen in the Linux kernel and reported by
+   Jakub Jelinek <jakub@redhat.com>; this test is synthetic.  */
+
+/* { dg-do compile } */
+
+#define glue(a,b) a##b
+#define struct(x) B(x)
+#define E(x) struct x
+#define FG (22)
+
+extern void B(int);
+
+void foo(void)
+{
+  E(glue(F,*)) dummy;  /* { dg-warning "valid preprocessing token" } */
+
+  E(glue(F,G)) ;
+}
diff --git a/gcc/testsuite/gcc.dg/cpp/vararg1.c b/gcc/testsuite/gcc.dg/cpp/vararg1.c
new file mode 100644 (file)
index 0000000..aa8ed79
--- /dev/null
@@ -0,0 +1,19 @@
+/* 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
+
+int
+main()
+{
+  const char *s = S("foo");
+  return strchr (s, '\n') == NULL;
+}
+