diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f5cab7463f33ff19a9193cff282010f629d50a2e..e9a68b3e8503b2e5d7fd19fe0d043233bce639bb 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 0000000000000000000000000000000000000000..ddd62c743b9a0e4635ee9b4630f26f6affaeb786
--- /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 0000000000000000000000000000000000000000..21576fa22fa438665b46dbf68a7dcaec79ee25f0
--- /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 99476d0c89f431c5aaf3f789dea94a2025e4603e..48b24ecfad98b858610a8447a12fea8255458abe 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 441b3b32ed30e12909cb2e2e821452c6eafefc14..daa2bd34a0e9ce0643ca02af01aa1343cfd30f5c 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);