From cae064e7982fb1a9f7e2fd8208e83199786aa39c Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Tue, 5 Apr 2005 22:07:06 +0200
Subject: [PATCH] re PR preprocessor/19475 (missing whitespace after macro name
 in C90 or C++)

	PR preprocessor/19475
	* macro.c (create_iso_definition): For < ISO C99, don't
	pedwarn if there is no whitespace between macro name and its
	replacement, but the replacement starts with a basic character
	set character.

	* gcc.dg/cpp/macspace1.c: New test.
	* gcc.dg/cpp/macspace2.c: New test.

From-SVN: r97652
---
 gcc/testsuite/ChangeLog              |  6 +++
 gcc/testsuite/gcc.dg/cpp/macspace1.c | 61 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/cpp/macspace2.c | 61 ++++++++++++++++++++++++++++
 libcpp/ChangeLog                     |  8 ++++
 libcpp/macro.c                       | 35 +++++++++++++++-
 5 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/cpp/macspace1.c
 create mode 100644 gcc/testsuite/gcc.dg/cpp/macspace2.c

diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f5cab7463f33..e9a68b3e8503 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2005-04-05  Jakub Jelinek  <jakub@redhat.com>
+
+	PR preprocessor/19475
+	* gcc.dg/cpp/macspace1.c: New test.
+	* gcc.dg/cpp/macspace2.c: New test.
+
 2005-04-05  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
 
 	* gfortran.dg/pr20755.f: Fixed bad format.
diff --git a/gcc/testsuite/gcc.dg/cpp/macspace1.c b/gcc/testsuite/gcc.dg/cpp/macspace1.c
new file mode 100644
index 000000000000..ddd62c743b9a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/macspace1.c
@@ -0,0 +1,61 @@
+/* PR preprocessor/19475 */
+/* { dg-do preprocess } */
+/* { dg-options "-std=iso9899:1990 -pedantic-errors -fno-show-column" } */
+
+#define a!		/* { dg-warning "missing whitespace" } */
+#define b"		/* { dg-warning "missing whitespace" } */
+#define c#		/* { dg-warning "missing whitespace" } */
+#define d%		/* { dg-warning "missing whitespace" } */
+#define e&		/* { dg-warning "missing whitespace" } */
+#define f'		/* { dg-warning "missing whitespace" } */
+#define g)		/* { dg-warning "missing whitespace" } */
+#define h*		/* { dg-warning "missing whitespace" } */
+#define i+		/* { dg-warning "missing whitespace" } */
+#define j,		/* { dg-warning "missing whitespace" } */
+#define k-		/* { dg-warning "missing whitespace" } */
+#define l.		/* { dg-warning "missing whitespace" } */
+#define m/		/* { dg-warning "missing whitespace" } */
+#define n:		/* { dg-warning "missing whitespace" } */
+#define o;		/* { dg-warning "missing whitespace" } */
+#define p<		/* { dg-warning "missing whitespace" } */
+#define q=		/* { dg-warning "missing whitespace" } */
+#define r>		/* { dg-warning "missing whitespace" } */
+#define s?		/* { dg-warning "missing whitespace" } */
+#define t[		/* { dg-warning "missing whitespace" } */
+#define u]		/* { dg-warning "missing whitespace" } */
+#define v^		/* { dg-warning "missing whitespace" } */
+#define w{		/* { dg-warning "missing whitespace" } */
+#define x|		/* { dg-warning "missing whitespace" } */
+#define y}		/* { dg-warning "missing whitespace" } */
+#define z~		/* { dg-warning "missing whitespace" } */
+#define A>>		/* { dg-warning "missing whitespace" } */
+#define B<<		/* { dg-warning "missing whitespace" } */
+#define E&&		/* { dg-warning "missing whitespace" } */
+#define F||		/* { dg-warning "missing whitespace" } */
+#define G==		/* { dg-warning "missing whitespace" } */
+#define H!=		/* { dg-warning "missing whitespace" } */
+#define I>=		/* { dg-warning "missing whitespace" } */
+#define J<=		/* { dg-warning "missing whitespace" } */
+#define K+=		/* { dg-warning "missing whitespace" } */
+#define L-=		/* { dg-warning "missing whitespace" } */
+#define M*=		/* { dg-warning "missing whitespace" } */
+#define N/=		/* { dg-warning "missing whitespace" } */
+#define O%=		/* { dg-warning "missing whitespace" } */
+#define P&=		/* { dg-warning "missing whitespace" } */
+#define Q|=		/* { dg-warning "missing whitespace" } */
+#define R^=		/* { dg-warning "missing whitespace" } */
+#define S>>=		/* { dg-warning "missing whitespace" } */
+#define T<<=		/* { dg-warning "missing whitespace" } */
+#define W...		/* { dg-warning "missing whitespace" } */
+#define X++		/* { dg-warning "missing whitespace" } */
+#define Y--		/* { dg-warning "missing whitespace" } */
+#define Z->		/* { dg-warning "missing whitespace" } */
+#define aa::		/* { dg-warning "missing whitespace" } */
+#define ab->*		/* { dg-warning "missing whitespace" } */
+#define ac.*		/* { dg-warning "missing whitespace" } */
+#define ad\x		/* { dg-warning "missing whitespace" } */
+#define ae\\x		/* { dg-warning "missing whitespace" } */
+#define af'1'		/* { dg-warning "missing whitespace" } */
+#define ag"abc"		/* { dg-warning "missing whitespace" } */
+
+int dummy;
diff --git a/gcc/testsuite/gcc.dg/cpp/macspace2.c b/gcc/testsuite/gcc.dg/cpp/macspace2.c
new file mode 100644
index 000000000000..21576fa22fa4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/macspace2.c
@@ -0,0 +1,61 @@
+/* PR preprocessor/19475 */
+/* { dg-do preprocess } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors -fno-show-column" } */
+
+#define a!		/* { dg-error "requires whitespace" } */
+#define b"		/* { dg-error "requires whitespace" } */
+#define c#		/* { dg-error "requires whitespace" } */
+#define d%		/* { dg-error "requires whitespace" } */
+#define e&		/* { dg-error "requires whitespace" } */
+#define f'		/* { dg-error "requires whitespace" } */
+#define g)		/* { dg-error "requires whitespace" } */
+#define h*		/* { dg-error "requires whitespace" } */
+#define i+		/* { dg-error "requires whitespace" } */
+#define j,		/* { dg-error "requires whitespace" } */
+#define k-		/* { dg-error "requires whitespace" } */
+#define l.		/* { dg-error "requires whitespace" } */
+#define m/		/* { dg-error "requires whitespace" } */
+#define n:		/* { dg-error "requires whitespace" } */
+#define o;		/* { dg-error "requires whitespace" } */
+#define p<		/* { dg-error "requires whitespace" } */
+#define q=		/* { dg-error "requires whitespace" } */
+#define r>		/* { dg-error "requires whitespace" } */
+#define s?		/* { dg-error "requires whitespace" } */
+#define t[		/* { dg-error "requires whitespace" } */
+#define u]		/* { dg-error "requires whitespace" } */
+#define v^		/* { dg-error "requires whitespace" } */
+#define w{		/* { dg-error "requires whitespace" } */
+#define x|		/* { dg-error "requires whitespace" } */
+#define y}		/* { dg-error "requires whitespace" } */
+#define z~		/* { dg-error "requires whitespace" } */
+#define A>>		/* { dg-error "requires whitespace" } */
+#define B<<		/* { dg-error "requires whitespace" } */
+#define E&&		/* { dg-error "requires whitespace" } */
+#define F||		/* { dg-error "requires whitespace" } */
+#define G==		/* { dg-error "requires whitespace" } */
+#define H!=		/* { dg-error "requires whitespace" } */
+#define I>=		/* { dg-error "requires whitespace" } */
+#define J<=		/* { dg-error "requires whitespace" } */
+#define K+=		/* { dg-error "requires whitespace" } */
+#define L-=		/* { dg-error "requires whitespace" } */
+#define M*=		/* { dg-error "requires whitespace" } */
+#define N/=		/* { dg-error "requires whitespace" } */
+#define O%=		/* { dg-error "requires whitespace" } */
+#define P&=		/* { dg-error "requires whitespace" } */
+#define Q|=		/* { dg-error "requires whitespace" } */
+#define R^=		/* { dg-error "requires whitespace" } */
+#define S>>=		/* { dg-error "requires whitespace" } */
+#define T<<=		/* { dg-error "requires whitespace" } */
+#define W...		/* { dg-error "requires whitespace" } */
+#define X++		/* { dg-error "requires whitespace" } */
+#define Y--		/* { dg-error "requires whitespace" } */
+#define Z->		/* { dg-error "requires whitespace" } */
+#define aa::		/* { dg-error "requires whitespace" } */
+#define ab->*		/* { dg-error "requires whitespace" } */
+#define ac.*		/* { dg-error "requires whitespace" } */
+#define ad\x		/* { dg-error "requires whitespace" } */
+#define ae\\x		/* { dg-error "requires whitespace" } */
+#define af'1'		/* { dg-error "requires whitespace" } */
+#define ag"abc"		/* { dg-error "requires whitespace" } */
+
+int dummy;
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 99476d0c89f4..48b24ecfad98 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,11 @@
+2005-04-05  Jakub Jelinek  <jakub@redhat.com>
+
+	PR preprocessor/19475
+	* macro.c (create_iso_definition): For < ISO C99, don't
+	pedwarn if there is no whitespace between macro name and its
+	replacement, but the replacement starts with a basic character
+	set character.
+
 2005-03-28  Andreas Jaeger  <aj@suse.de>
 
 	* lex.c (warn_about_normalization): Cast field width to int to
diff --git a/libcpp/macro.c b/libcpp/macro.c
index 441b3b32ed30..daa2bd34a0e9 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -1430,8 +1430,39 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
       macro->fun_like = 1;
     }
   else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE))
-    cpp_error (pfile, CPP_DL_PEDWARN,
-	       "ISO C requires whitespace after the macro name");
+    {
+      /* While ISO C99 requires whitespace before replacement text
+	 in a macro definition, ISO C90 with TC1 allows there characters
+	 from the basic source character set.  */
+      if (CPP_OPTION (pfile, c99))
+	cpp_error (pfile, CPP_DL_PEDWARN,
+		   "ISO C99 requires whitespace after the macro name");
+      else
+	{
+	  int warntype = CPP_DL_WARNING;
+	  switch (ctoken->type)
+	    {
+	    case CPP_ATSIGN:
+	    case CPP_AT_NAME:
+	    case CPP_OBJC_STRING:
+	      /* '@' is not in basic character set.  */
+	      warntype = CPP_DL_PEDWARN;
+	      break;
+	    case CPP_OTHER:
+	      /* Basic character set sans letters, digits and _.  */
+	      if (strchr ("!\"#%&'()*+,-./:;<=>?[\\]^{|}~",
+			  ctoken->val.str.text[0]) == NULL)
+		warntype = CPP_DL_PEDWARN;
+	      break;
+	    default:
+	      /* All other tokens start with a character from basic
+		 character set.  */
+	      break;
+	    }
+	  cpp_error (pfile, warntype,
+		     "missing whitespace after the macro name");
+	}
+    }
 
   if (macro->fun_like)
     token = lex_expansion_token (pfile, macro);
-- 
GitLab