OSDN Git Service

libcpp/
authorjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Apr 2009 17:04:42 +0000 (17:04 +0000)
committerjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Apr 2009 17:04:42 +0000 (17:04 +0000)
PR c/33466
* expr.c (interpret_float_suffix): Reject invalid suffix that uses
letters from decimal float and fixed-point suffixes.

gcc/testsuite
PR c/33466
* gcc.dg/cpp/pr33466.c: New test.
* gcc.dg/dfp/pr33466.c: New test.
* gcc.dg/fixed-point/pr33466.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145417 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/pr33466.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/pr33466.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/fixed-point/pr33466.c [new file with mode: 0644]
libcpp/ChangeLog
libcpp/expr.c

index 77df8ab..3723cb7 100644 (file)
@@ -1,3 +1,10 @@
+2009-04-01  Janis Johnson  <janis187@us.ibm.com>
+
+       PR c/33466
+       * gcc.dg/cpp/pr33466.c: New test.
+       * gcc.dg/dfp/pr33466.c: New test.
+       * gcc.dg/fixed-point/pr33466.c: New test.
+
 2009-04-01  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR tree-optimization/35011
diff --git a/gcc/testsuite/gcc.dg/cpp/pr33466.c b/gcc/testsuite/gcc.dg/cpp/pr33466.c
new file mode 100644 (file)
index 0000000..8ddb37c
--- /dev/null
@@ -0,0 +1,64 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+/* Test various invalid constant float suffixes made up of letters of
+   valid suffixes.  These are invalid regardless of whether the target
+   compiler supports decimal float or fixed-point types.  */
+
+long double rh = 0.5rh;                /* { dg-error "invalid suffix" } */
+long double rl = 0.5rl;                /* { dg-error "invalid suffix" } */
+long double rll = 0.5rll;      /* { dg-error "invalid suffix" } */
+long double kh = 0.5kh;                /* { dg-error "invalid suffix" } */
+long double kl = 0.5kl;                /* { dg-error "invalid suffix" } */
+long double kll = 0.5kll;      /* { dg-error "invalid suffix" } */
+long double ru = 0.5ru;                /* { dg-error "invalid suffix" } */
+long double urh = 0.5urh;      /* { dg-error "invalid suffix" } */
+long double hur = 0.5hur;      /* { dg-error "invalid suffix" } */
+long double hru = 0.5hru;      /* { dg-error "invalid suffix" } */
+long double ruh = 0.5ruh;      /* { dg-error "invalid suffix" } */
+long double rhu = 0.5rhu;      /* { dg-error "invalid suffix" } */
+long double url = 0.5url;      /* { dg-error "invalid suffix" } */
+long double lur = 0.5lur;      /* { dg-error "invalid suffix" } */
+long double lru = 0.5lru;      /* { dg-error "invalid suffix" } */
+long double rul = 0.5rul;      /* { dg-error "invalid suffix" } */
+long double rlu = 0.5rlu;      /* { dg-error "invalid suffix" } */
+long double urll = 0.5urll;    /* { dg-error "invalid suffix" } */
+long double llur = 0.5llur;    /* { dg-error "invalid suffix" } */
+long double llru = 0.5llru;    /* { dg-error "invalid suffix" } */
+long double rull = 0.5rull;    /* { dg-error "invalid suffix" } */
+long double rllu = 0.5rllu;    /* { dg-error "invalid suffix" } */
+long double ku = 0.5ku;                /* { dg-error "invalid suffix" } */
+long double ukh = 0.5ukh;      /* { dg-error "invalid suffix" } */
+long double huk = 0.5huk;      /* { dg-error "invalid suffix" } */
+long double hku = 0.5hku;      /* { dg-error "invalid suffix" } */
+long double kuh = 0.5kuh;      /* { dg-error "invalid suffix" } */
+long double khu = 0.5khu;      /* { dg-error "invalid suffix" } */
+long double ukl = 0.5ukl;      /* { dg-error "invalid suffix" } */
+long double luk = 0.5luk;      /* { dg-error "invalid suffix" } */
+long double lku = 0.5lku;      /* { dg-error "invalid suffix" } */
+long double kul = 0.5kul;      /* { dg-error "invalid suffix" } */
+long double klu = 0.5klu;      /* { dg-error "invalid suffix" } */
+long double ukll = 0.5ukll;    /* { dg-error "invalid suffix" } */
+long double lluk = 0.5lluk;    /* { dg-error "invalid suffix" } */
+long double llku = 0.5llku;    /* { dg-error "invalid suffix" } */
+long double kull = 0.5kull;    /* { dg-error "invalid suffix" } */
+long double kllu = 0.5kllu;    /* { dg-error "invalid suffix" } */
+long double ld = 0.5ld;                /* { dg-error "invalid suffix" } */
+long double fd = 0.5fd;                /* { dg-error "invalid suffix" } */
+long double dk = 0.5dk;                /* { dg-error "invalid suffix" } */
+long double dr = 0.5dr;                /* { dg-error "invalid suffix" } */
+long double ddw = 0.5ddw;      /* { dg-error "invalid suffix" } */
+long double ddq = 0.5ddq;      /* { dg-error "invalid suffix" } */
+long double ddl = 0.5ddl;      /* { dg-error "invalid suffix" } */
+long double ddf = 0.5ddf;      /* { dg-error "invalid suffix" } */
+long double ddd = 0.5ddd;      /* { dg-error "invalid suffix" } */
+long double dw = 0.5dw;                /* { dg-error "invalid suffix" } */
+long double dq = 0.5dq;                /* { dg-error "invalid suffix" } */
+long double wd = 0.5wd;                /* { dg-error "invalid suffix" } */
+long double qd = 0.5qd;                /* { dg-error "invalid suffix" } */
+long double wdd = 0.5wdd;      /* { dg-error "invalid suffix" } */
+long double qdd = 0.5qdd;      /* { dg-error "invalid suffix" } */
+long double ldd = 0.5ldd;      /* { dg-error "invalid suffix" } */
+long double fdd = 0.5fdd;      /* { dg-error "invalid suffix" } */
+long double ddi = 0.5ddi;      /* { dg-error "invalid suffix" } */
+long double idd = 0.5idd;      /* { dg-error "invalid suffix" } */
diff --git a/gcc/testsuite/gcc.dg/dfp/pr33466.c b/gcc/testsuite/gcc.dg/dfp/pr33466.c
new file mode 100644 (file)
index 0000000..c8ac111
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+/* The suffix for a decimal float constant must use a single case.
+
+   These are invalid for all targets, not just those that support
+    decimal float.  */
+
+long double dF = 4.5dF;                /* { dg-error "invalid suffix" } */
+long double Df = 4.5Df;                /* { dg-error "invalid suffix" } */
+long double dD = 4.5dD;                /* { dg-error "invalid suffix" } */
+long double Dd = 4.5Dd;                /* { dg-error "invalid suffix" } */
+long double dL = 4.5dL;                /* { dg-error "invalid suffix" } */
+long double Dl = 4.5Dl;                /* { dg-error "invalid suffix" } */
diff --git a/gcc/testsuite/gcc.dg/fixed-point/pr33466.c b/gcc/testsuite/gcc.dg/fixed-point/pr33466.c
new file mode 100644 (file)
index 0000000..196db31
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+/* The suffix for a fixed-point constant must use a specific order
+   for the pieces, and a long long length specifier must use the
+   same case (ll or LL).
+
+   These are invalid for all targets, not just those that support
+   fixed-point types.  */
+
+long double lLr = 0.5lLr;      /* { dg-error "invalid suffix" } */
+long double lLR = 0.5lLR;      /* { dg-error "invalid suffix" } */
+long double Llr = 0.5Llr;      /* { dg-error "invalid suffix" } */
+long double LlR = 0.5LlR;      /* { dg-error "invalid suffix" } */
+long double ulLr = 0.5ulLr;    /* { dg-error "invalid suffix" } */
+long double ulLR = 0.5ulLR;    /* { dg-error "invalid suffix" } */
+long double uLlr = 0.5uLlr;    /* { dg-error "invalid suffix" } */
+long double uLlR = 0.5uLlR;    /* { dg-error "invalid suffix" } */
+long double UlLr = 0.5UlLr;    /* { dg-error "invalid suffix" } */
+long double UlLR = 0.5UlLR;    /* { dg-error "invalid suffix" } */
+long double ULlr = 0.5ULlr;    /* { dg-error "invalid suffix" } */
+long double ULlR = 0.5ULlR;    /* { dg-error "invalid suffix" } */
+long double lLk = 0.5lLk;      /* { dg-error "invalid suffix" } */
+long double lLK = 0.5lLK;      /* { dg-error "invalid suffix" } */
+long double Llk = 0.5Llk;      /* { dg-error "invalid suffix" } */
+long double LlK = 0.5LlK;      /* { dg-error "invalid suffix" } */
+long double ulLk = 0.5ulLk;    /* { dg-error "invalid suffix" } */
+long double ulLK = 0.5ulLK;    /* { dg-error "invalid suffix" } */
+long double uLlk = 0.5uLlk;    /* { dg-error "invalid suffix" } */
+long double uLlK = 0.5uLlK;    /* { dg-error "invalid suffix" } */
+long double UlLk = 0.5UlLk;    /* { dg-error "invalid suffix" } */
+long double UlLK = 0.5UlLK;    /* { dg-error "invalid suffix" } */
+long double ULlk = 0.5ULlk;    /* { dg-error "invalid suffix" } */
+long double ULlK = 0.5ULlK;    /* { dg-error "invalid suffix" } */
index e16a9e4..c7c7239 100644 (file)
@@ -1,3 +1,9 @@
+2009-04-01  Janis Johnson  <janis187@us.ibm.com>
+
+       PR c/33466
+       * expr.c (interpret_float_suffix): Reject invalid suffix that uses
+       letters from decimal float and fixed-point suffixes.
+
 2009-03-31  Joseph Myers  <joseph@codesourcery.com>
 
        PR preprocessor/15638
index 591308b..dbbb05a 100644 (file)
@@ -83,89 +83,102 @@ static void check_promotion (cpp_reader *, const struct op *);
 static unsigned int
 interpret_float_suffix (const uchar *s, size_t len)
 {
-  size_t f, l, w, q, i, d;
-  size_t r, k, u, h;
+  size_t flags;
+  size_t f, l, w, q, i;
 
-  f = l = w = q = i = d = 0;
-  r = k = u = h = 0;
+  flags = 0;
+  f = l = w = q = i = 0;
 
-  while (len--)
-    switch (s[len])
+  /* Process decimal float suffixes, which are two letters starting
+     with d or D.  Order and case are significant.  */
+  if (len == 2 && (*s == 'd' || *s == 'D'))
+    {
+      bool uppercase = (*s == 'D');
+      switch (s[1])
       {
-      case 'r': case 'R': r++; break;
-      case 'k': case 'K': k++; break;
-      case 'u': case 'U': u++; break;
-      case 'h': case 'H': h++; break;
-      case 'f': case 'F':
-       if (d > 0)
-         return 0;
-       f++;
-       break;
-      case 'l': case 'L':
-       if (d > 0)
-         return 0;
-       l++;
-       /* If there are two Ls, they must be adjacent and the same case.  */
-       if (l == 2 && s[len] != s[len + 1])
-         return 0;
-       break;
-      case 'w': case 'W':
-       if (d > 0)
-         return 0;
-       w++;
-       break;
-      case 'q': case 'Q':
-       if (d > 0)
-         return 0;
-       q++;
-       break;
-      case 'i': case 'I':
-      case 'j': case 'J': i++; break;
-      case 'd': case 'D': d++; break;
+      case 'f': return (!uppercase ? (CPP_N_DFLOAT | CPP_N_SMALL): 0); break;
+      case 'F': return (uppercase ? (CPP_N_DFLOAT | CPP_N_SMALL) : 0); break;
+      case 'd': return (!uppercase ? (CPP_N_DFLOAT | CPP_N_MEDIUM): 0); break;
+      case 'D': return (uppercase ? (CPP_N_DFLOAT | CPP_N_MEDIUM) : 0); break;
+      case 'l': return (!uppercase ? (CPP_N_DFLOAT | CPP_N_LARGE) : 0); break;
+      case 'L': return (uppercase ? (CPP_N_DFLOAT | CPP_N_LARGE) : 0); break;
       default:
        return 0;
       }
+    }
 
-  if (r + k > 1 || h > 1 || l > 2 || u > 1)
-    return 0;
-
-  if (r == 1)
+  /* Recognize a fixed-point suffix.  */
+  switch (s[len-1])
     {
-      if (f || i || d || w || q)
-       return 0;
-
-      return (CPP_N_FRACT
-             | (u ? CPP_N_UNSIGNED : 0)
-             | (h ? CPP_N_SMALL :
-                l == 2 ? CPP_N_LARGE :
-                l == 1 ? CPP_N_MEDIUM :  0));
+    case 'k': case 'K': flags = CPP_N_ACCUM; break;
+    case 'r': case 'R': flags = CPP_N_FRACT; break;
+    default: break;
     }
 
-  if (k == 1)
+  /* Continue processing a fixed-point suffix.  The suffix is case
+     insensitive except for ll or LL.  Order is significant.  */
+  if (flags)
     {
-      if (f || i || d || w || q)
-       return 0;
+      if (len == 1)
+       return flags;
+      len--;
+
+      if (*s == 'u' || *s == 'U')
+       {
+         flags |= CPP_N_UNSIGNED;
+         if (len == 1)
+           return flags;
+         len--;
+         s++;
+        }
 
-      return (CPP_N_ACCUM
-             | (u ? CPP_N_UNSIGNED : 0)
-             | (h ? CPP_N_SMALL :
-                l == 2 ? CPP_N_LARGE :
-                l == 1 ? CPP_N_MEDIUM :  0));
+      switch (*s)
+      {
+      case 'h': case 'H':
+       if (len == 1)
+         return flags |= CPP_N_SMALL;
+       break;
+      case 'l':
+       if (len == 1)
+         return flags |= CPP_N_MEDIUM;
+       if (len == 2 && s[1] == 'l')
+         return flags |= CPP_N_LARGE;
+       break;
+      case 'L':
+       if (len == 1)
+         return flags |= CPP_N_MEDIUM;
+       if (len == 2 && s[1] == 'L')
+         return flags |= CPP_N_LARGE;
+       break;
+      default:
+       break;
+      }
+      /* Anything left at this point is invalid.  */
+      return 0;
     }
 
-  if (f + l + w + q > 1 || i > 1 || h + u > 0)
-    return 0;
+  /* In any remaining valid suffix, the case and order don't matter.  */
+  while (len--)
+    switch (s[len])
+      {
+      case 'f': case 'F': f++; break;
+      case 'l': case 'L': l++; break;
+      case 'w': case 'W': w++; break;
+      case 'q': case 'Q': q++; break;
+      case 'i': case 'I':
+      case 'j': case 'J': i++; break;
+      default:
+       return 0;
+      }
 
-  /* Allow dd, df, dl suffixes for decimal float constants.  */
-  if (d && ((d + f + l != 2) || i))
+  if (f + l + w + q > 1 || i > 1)
     return 0;
 
   return ((i ? CPP_N_IMAGINARY : 0)
          | (f ? CPP_N_SMALL :
             l ? CPP_N_LARGE :
             w ? CPP_N_MD_W :
-            q ? CPP_N_MD_Q : CPP_N_MEDIUM)
-         | (d ? CPP_N_DFLOAT : 0));
+            q ? CPP_N_MD_Q : CPP_N_MEDIUM));
 }
 
 /* Subroutine of cpp_classify_number.  S points to an integer suffix