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]

Space between backslash and newline; heavily nested macros


This patch does two things.  First, in most cases cpp will now treat a
backslash-newline as a line continuation even if there is trailing
whitespace.  A warning is generated when this happens.  Don't write
code that depends on this behavior; it is provided because trailing
whitespace is significant (almost) nowhere else, and we get much
better error recovery if we treat them as line continuations.
Especially don't write code that depends on being able to put a
comment after a line continuation, that is an accident of the
implementation and will change in the future.

Second, and much less earth-shatteringly, there is now no hard limit
on the number of nested macro invocations.  If you have a long
sequence of

#define a 1
#define b a+1
#define c b+1
...

with more than 200 macros in the chain, and you used the last one, the
code used to be rejected; no more.  (You should still use an enum
instead.)  The ISO C prohibition of macro recursion suffices to avoid
infinite macro nesting.

There is still a limit of 200 nested #includes.

Bootstrapped i386-linux with the new test case.  Will apply shortly.

zw

	* cpplex.c (parse_string): Accept backslash space newline as a
	line continuation.
	(lex_line): Likewise.
	(_cpp_get_token): Remove hard limit on macro nesting.

	* gcc.dg/cpp/backslash.c: New test.

===================================================================
Index: cpplex.c
--- cpplex.c	2000/09/04 07:51:57	1.94
+++ cpplex.c	2000/09/12 03:26:36
@@ -1106,12 +1106,23 @@ parse_string (pfile, list, token, termin
 	  if (is_vspace (c))
 	    {
 	      /* Drop a backslash newline, and continue. */
+	      U_CHAR *old = namebuf;
+	      while (namebuf > list->namebuf && is_hspace (namebuf[-1]))
+		namebuf--;
 	      if (namebuf > list->namebuf && namebuf[-1] == '\\')
 		{
 		  handle_newline (cur, buffer->rlimit, c);
 		  namebuf--;
+		  if (old[-1] != '\\')
+		    {
+		      buffer->cur = cur;
+		      cpp_warning (pfile,
+				   "backslash and newline separated by space");
+		    }
 		  continue;
 		}
+	      else
+		namebuf = old;
 
 	      cur--;
 
@@ -1516,37 +1527,40 @@ lex_line (pfile, list)
 	  handle_newline (cur, buffer->rlimit, c);
 	  if (PREV_TOKEN_TYPE == CPP_BACKSLASH)
 	    {
-	      if (IMMED_TOKEN ())
-		{
-		  /* Remove the escaped newline.  Then continue to process
-		     any interrupted name or number.  */
-		  cur_token--;
-		  /* Backslash-newline may not be immediately followed by
-		     EOF (C99 5.1.1.2).  */
-		  if (cur >= buffer->rlimit)
-		    {
-		      cpp_pedwarn (pfile, "backslash-newline at end of file");
-		      break;
-		    }
-		  if (IMMED_TOKEN ())
-		    {
-		      cur_token--;
-		      if (cur_token->type == CPP_NAME)
-			goto continue_name;
-		      else if (cur_token->type == CPP_NUMBER)
-			goto continue_number;
-		      cur_token++;
-		    }
-		  /* Remember whitespace setting.  */
-		  flags = cur_token->flags;
-		  break;
-		}
-	      else
+	      /* backslash space newline is still treated as backslash-newline;
+		 we think this is standard conforming, with some reservations
+		 about actually _using_ the weasel words in C99 5.1.1.2
+		 (translation phase 1 is allowed to do whatever it wants to
+		 your input as long as it's documented).  */
+	      if (! IMMED_TOKEN ())
 		{
 		  buffer->cur = cur;
 		  cpp_warning (pfile,
 			       "backslash and newline separated by space");
 		}
+	      
+	      /* Remove the escaped newline.  Then continue to process
+		 any interrupted name or number.  */
+	      cur_token--;
+	      /* Backslash-newline may not be immediately followed by
+		 EOF (C99 5.1.1.2).  */
+	      if (cur >= buffer->rlimit)
+		{
+		  cpp_pedwarn (pfile, "backslash-newline at end of file");
+		  break;
+		}
+	      if (IMMED_TOKEN ())
+		{
+		  cur_token--;
+		  if (cur_token->type == CPP_NAME)
+		    goto continue_name;
+		  else if (cur_token->type == CPP_NUMBER)
+		    goto continue_number;
+		  cur_token++;
+		}
+	      /* Remember whitespace setting.  */
+	      flags = cur_token->flags;
+	      break;
 	    }
 	  else if (MIGHT_BE_DIRECTIVE ())
 	    {
@@ -3186,12 +3200,6 @@ _cpp_get_token (pfile)
 
       if (is_macro_disabled (pfile, node->value.expansion, token))
 	return token;
-
-      if (pfile->cur_context > CPP_STACK_MAX)
-	{
-	  cpp_error (pfile, "macros nested too deep invoking '%s'", node->name);
-	  return token;
-	}
 
       if (push_macro_context (pfile, token))
 	return token;
===================================================================
Index: testsuite/gcc.dg/cpp/backslash.c
--- testsuite/gcc.dg/cpp/backslash.c	Tue May  5 13:32:27 1998
+++ testsuite/gcc.dg/cpp/backslash.c	Mon Sep 11 20:26:37 2000
@@ -0,0 +1,21 @@
+/* Test backslash newline with and without trailing spaces.  */
+
+#define alpha(a, b, c) \
+	a, \
+	b, \
+	c
+
+/* Note the trailing whitespace on the next three lines.  */
+#define beta(a, b, c) \ 
+	a, \	
+	b, \ 	
+	c
+
+/* { dg-warning "separated by space" "space" { target *-*-* } 9 } */
+/* { dg-warning "separated by space" "tab" { target *-*-* } 10 } */
+/* { dg-warning "separated by space" "space and tab" { target *-*-* } 11 } */
+
+int x[] = {
+   alpha(1, 2, 3),
+   beta(4, 5, 6)
+};


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