diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 312cb9899efdc1ba7c4dc28bcb97183bcf8784ce..d96b55f07a6d116e29fa7f9147de00a19832ecd4 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,11 @@
+2005-12-07  Jon Grimm  <jgrimm2@us.ibm.com>
+	    Ben Elliston  <bje@au.ibm.com>
+
+	* include/cpplib.h (CPP_N_DFLOAT): New.
+	* expr.c (interpret_float_suffix): Identify df, dd, and dl
+	suffixes as decimal floating point constants.
+	(cpp_classify_number): Disallow hexadecimal DFP constants.
+
 2005-11-14  Gerald Pfeifer  <gerald@pfeifer.com>
             Ian Lance Taylor  <ian@airs.com>
 
diff --git a/libcpp/expr.c b/libcpp/expr.c
index 32b1723830987651451012d7c396c32ecf60dbde..a61ff665ec0fa13dbd5556930317b380ab212b1c 100644
--- a/libcpp/expr.c
+++ b/libcpp/expr.c
@@ -82,7 +82,7 @@ static void check_promotion (cpp_reader *, const struct op *);
 static unsigned int
 interpret_float_suffix (const uchar *s, size_t len)
 {
-  size_t f = 0, l = 0, i = 0;
+  size_t f = 0, l = 0, i = 0, d = 0;
 
   while (len--)
     switch (s[len])
@@ -91,6 +91,12 @@ interpret_float_suffix (const uchar *s, size_t len)
       case 'l': case 'L': l++; break;
       case 'i': case 'I':
       case 'j': case 'J': i++; break;
+      case 'd': case 'D': 
+	/* Disallow fd, ld suffixes.  */
+	if (d && (f || l))
+	  return 0;
+	d++;
+	break;
       default:
 	return 0;
       }
@@ -98,9 +104,14 @@ interpret_float_suffix (const uchar *s, size_t len)
   if (f + l > 1 || i > 1)
     return 0;
 
+  /* Allow dd, df, dl suffixes for decimal float constants.  */
+  if (d && ((d + f + l != 2) || i))
+    return 0;
+
   return ((i ? CPP_N_IMAGINARY : 0)
 	  | (f ? CPP_N_SMALL :
-	     l ? CPP_N_LARGE : CPP_N_MEDIUM));
+	     l ? CPP_N_LARGE : CPP_N_MEDIUM)
+	  | (d ? CPP_N_DFLOAT : 0));
 }
 
 /* Subroutine of cpp_classify_number.  S points to an integer suffix
@@ -250,6 +261,15 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
 		   "traditional C rejects the \"%.*s\" suffix",
 		   (int) (limit - str), str);
 
+      /* Radix must be 10 for decimal floats.  */
+      if ((result & CPP_N_DFLOAT) && radix != 10)
+        {
+          cpp_error (pfile, CPP_DL_ERROR,
+                     "invalid suffix \"%.*s\" with hexadecimal floating constant",
+                     (int) (limit - str), str);
+          return CPP_N_INVALID;
+        }
+
       result |= CPP_N_FLOATING;
     }
   else
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 9ec022f6dfc61e73703c9efb02c4f83da94c3d8e..b5bece5e5d60bc9789de3b2222e5c1c777868a3b 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -743,6 +743,7 @@ struct cpp_num
 
 #define CPP_N_UNSIGNED	0x1000	/* Properties.  */
 #define CPP_N_IMAGINARY	0x2000
+#define CPP_N_DFLOAT	0x4000
 
 /* Classify a CPP_NUMBER token.  The return value is a combination of
    the flags from the above sets.  */