Commit ce73f2a5 by Richard Stallman

(parse_number): Diagnose integer constants that are too large.

Diagnose duplicate `l' and `u' suffixes.  Diagnose ` 0x ' and ` 0a '.
Warn about integer constants that are so large that they are unsigned.

From-SVN: r2121
parent c832a30e
...@@ -342,10 +342,12 @@ parse_number (olen) ...@@ -342,10 +342,12 @@ parse_number (olen)
int olen; int olen;
{ {
register char *p = lexptr; register char *p = lexptr;
register long n = 0;
register int c; register int c;
register unsigned long n = 0, nd, ULONG_MAX_over_base;
register int base = 10; register int base = 10;
register int len = olen; register int len = olen;
register int overflow = 0;
int spec_long = 0;
for (c = 0; c < len; c++) for (c = 0; c < len; c++)
if (p[c] == '.') { if (p[c] == '.') {
...@@ -364,31 +366,43 @@ parse_number (olen) ...@@ -364,31 +366,43 @@ parse_number (olen)
else if (*p == '0') else if (*p == '0')
base = 8; base = 8;
while (len > 0) { ULONG_MAX_over_base = (unsigned long) -1 / base;
for (; len > 0; len--) {
c = *p++; c = *p++;
len--;
if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
n *= base; overflow |= ULONG_MAX_over_base < n;
n += c - '0'; nd = n * base + c - '0';
overflow |= nd < n;
n = nd;
} else if (base == 16 && c >= 'a' && c <= 'f') { } else if (base == 16 && c >= 'a' && c <= 'f') {
n *= base; overflow |= ULONG_MAX_over_base < n;
n += c - 'a' + 10; nd = n * 16 + c - 'a' + 10;
overflow |= nd < n;
n = nd;
} else { } else {
/* `l' means long, and `u' means unsigned. */ /* `l' means long, and `u' means unsigned. */
while (1) { while (1) {
if (c == 'l' || c == 'L') if (c == 'l' || c == 'L')
; {
if (spec_long)
yyerror ("two `l's in integer constant");
spec_long = 1;
}
else if (c == 'u' || c == 'U') else if (c == 'u' || c == 'U')
yylval.integer.unsignedp = 1; {
if (yylval.integer.unsignedp)
yyerror ("two `u's in integer constant");
yylval.integer.unsignedp = 1;
}
else else
break; break;
if (len == 0) if (--len == 0)
break; break;
c = *p++; c = *p++;
len--;
} }
/* Don't look for any more digits after the suffixes. */ /* Don't look for any more digits after the suffixes. */
break; break;
...@@ -400,9 +414,16 @@ parse_number (olen) ...@@ -400,9 +414,16 @@ parse_number (olen)
return ERROR; return ERROR;
} }
if (overflow)
warning ("integer constant out of range");
/* If too big to be signed, consider it unsigned. */ /* If too big to be signed, consider it unsigned. */
if (n < 0) if ((long) n < 0 && ! yylval.integer.unsignedp)
yylval.integer.unsignedp = 1; {
if (base == 10)
warning ("integer constant is so large that it is unsigned");
yylval.integer.unsignedp = 1;
}
lexptr = p; lexptr = p;
yylval.integer.value = n; yylval.integer.value = n;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment