aboutsummaryrefslogtreecommitdiff
path: root/libcpp/expr.c
diff options
context:
space:
mode:
authorJanis Johnson <janis187@us.ibm.com>2009-04-01 17:04:42 +0000
committerJanis Johnson <janis@gcc.gnu.org>2009-04-01 17:04:42 +0000
commiteec49116064299fcd6ce9a1fbc0e45b914f14a15 (patch)
tree03c9e0cc5126cdeaeacf71743476447cbfcfadbc /libcpp/expr.c
parentc4e751024524920e060b1c2fcbcc15423d86ac2c (diff)
downloadgcc-eec49116064299fcd6ce9a1fbc0e45b914f14a15.zip
gcc-eec49116064299fcd6ce9a1fbc0e45b914f14a15.tar.gz
gcc-eec49116064299fcd6ce9a1fbc0e45b914f14a15.tar.bz2
re PR c/33466 (mixed-case suffix for decimal float constants)
libcpp/ 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. From-SVN: r145417
Diffstat (limited to 'libcpp/expr.c')
-rw-r--r--libcpp/expr.c137
1 files changed, 75 insertions, 62 deletions
diff --git a/libcpp/expr.c b/libcpp/expr.c
index 591308b..dbbb05a 100644
--- a/libcpp/expr.c
+++ b/libcpp/expr.c
@@ -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