This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR preprocessor/20077: GCC accepts macro definitions that fail a constraint


Hello Joseph.

Thanks for the quick feedback.

> By moving this string here it will no longer be extracted for translation
> like it would as an argument to cpp_error.  You need to write
> N_("'##' cannot appear at either end of a macro expansion")
> instead so that it still gets extracted.
I did not know about this, sorry. Here is the corrected patch, bootstrapped on 
i686-pc-linux-gnu.

Best regards,
Simon
2006-10-17  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:
	one checks that macro->count is not equal to one when a token-pasting
	operator is encountered (if it is, the token is the first one in the
	macro) and that the previous token was not a token-pasting operator when
	the end of the macro is reached.
Index: libcpp/macro.c
===================================================================
--- libcpp/macro.c	(revision 117789)
+++ libcpp/macro.c	(working copy)
@@ -1422,6 +1422,9 @@ create_iso_definition (cpp_reader *pfile
 {
   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).  */
@@ -1515,26 +1518,34 @@ create_iso_definition (cpp_reader *pfile
 	}
 
       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);
     }
 
2006-10-17  Simon Martin  <simartin@users.sourceforge.net>

	PR preprocessor/20077
	* gcc.dg/cpp/paste15.c: New test.
/* 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" } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]