From 3b6c638ead814ff8cb8e7311f2c717a1ec850f92 Mon Sep 17 00:00:00 2001
From: simartin <simartin@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Wed, 23 May 2007 20:58:34 +0000
Subject: [PATCH] 2007-05-23  Simon Martin  <simartin@users.sourceforge.net>

	PR preprocessor/20077
	* macro.c (create_iso_definition): Fixed the method to determine whether
	the token-pasting operator appears at the beginning or the end of a macro.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@125000 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/testsuite/ChangeLog            |  5 +++++
 gcc/testsuite/gcc.dg/cpp/paste15.c | 15 +++++++++++++++
 libcpp/ChangeLog                   |  7 +++++++
 libcpp/macro.c                     | 27 +++++++++++++++++++--------
 4 files changed, 46 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/cpp/paste15.c

diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 988a41ba5610..03f611250493 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-05-23  Simon Martin  <simartin@users.sourceforge.net>
+
+	PR preprocessor/20077
+	* gcc.dg/cpp/paste15.c: New test.
+
 2007-05-23  Sandra Loosemore  <sandra@codesourcery.com>
 	    Nigel Stephens  <nigel@mips.com>
 	    Richard Sandiford  <richard@codesourcery.com>
diff --git a/gcc/testsuite/gcc.dg/cpp/paste15.c b/gcc/testsuite/gcc.dg/cpp/paste15.c
new file mode 100644
index 000000000000..9d4ec36315c0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/paste15.c
@@ -0,0 +1,15 @@
+/* PR preprocessor/20077 */
+/* { dg-do preprocess } */
+
+#define a   a ## ## /* { dg-error "end of a macro expansion" } */
+#define b() b ## ## /* { dg-error "end of a macro expansion" } */
+#define c   c ##    /* { dg-error "end of a macro expansion" } */
+#define d() d ##    /* { dg-error "end of a macro expansion" } */
+
+
+#define e   ## ## e /* { dg-error "end of a macro expansion" } */
+#define f() ## ## f /* { dg-error "end of a macro expansion" } */
+#define g   ## g    /* { dg-error "end of a macro expansion" } */
+#define h() ## h    /* { dg-error "end of a macro expansion" } */
+#define i   ##      /* { dg-error "end of a macro expansion" } */
+#define j() ##      /* { dg-error "end of a macro expansion" } */
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 44023594743b..8f760cc1d959 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,10 @@
+2007-05-23  Simon Martin  <simartin@users.sourceforge.net>
+
+	PR preprocessor/20077
+	* macro.c (create_iso_definition): Fixed the method to determine
+	whether the token-pasting operator appears at the beginning or the end
+	of a macro.
+
 2007-05-21  Ian Lance Taylor  <iant@google.com>
 
 	* internal.h (struct cpp_reader): Add new fields:
diff --git a/libcpp/macro.c b/libcpp/macro.c
index 748635f408ed..12681c343388 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -1434,6 +1434,9 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
 {
   cpp_token *token;
   const cpp_token *ctoken;
+  bool following_paste_op = false;
+  const char *paste_op_error_msg =
+    N_("'##' cannot appear at either end of a macro expansion");
 
   /* Get the first token of the expansion (or the '(' of a
      function-like macro).  */
@@ -1527,26 +1530,34 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
 	}
 
       if (token->type == CPP_EOF)
-	break;
+	{
+	  /* Paste operator constraint 6.10.3.3.1:
+	     Token-paste ##, can appear in both object-like and
+	     function-like macros, but not at the end.  */
+	  if (following_paste_op)
+	    {
+	      cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg);
+	      return false;
+	    }
+	  break;
+	}
 
       /* Paste operator constraint 6.10.3.3.1.  */
       if (token->type == CPP_PASTE)
 	{
 	  /* Token-paste ##, can appear in both object-like and
-	     function-like macros, but not at the ends.  */
-	  if (--macro->count > 0)
-	    token = lex_expansion_token (pfile, macro);
-
-	  if (macro->count == 0 || token->type == CPP_EOF)
+	     function-like macros, but not at the beginning.  */
+	  if (macro->count == 1)
 	    {
-	      cpp_error (pfile, CPP_DL_ERROR,
-		 "'##' cannot appear at either end of a macro expansion");
+	      cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg);
 	      return false;
 	    }
 
+	  --macro->count;
 	  token[-1].flags |= PASTE_LEFT;
 	}
 
+      following_paste_op = (token->type == CPP_PASTE);
       token = lex_expansion_token (pfile, macro);
     }
 
-- 
GitLab