mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-28 23:58:41 +08:00
tccpp.c: Improve integer constant overflow warning
Improve the warning about an integer constant overflow with the used overflown value and the potentially aimed value. This helps spotting the 0 to much in 0x80000000000000000.
This commit is contained in:
parent
fada98b1ce
commit
085bdf8997
36
tccpp.c
36
tccpp.c
@ -1995,7 +1995,7 @@ ST_FUNC void preprocess(int is_bof)
|
|||||||
if (tok == '!' && is_bof)
|
if (tok == '!' && is_bof)
|
||||||
/* '#!' is ignored at beginning to allow C scripts. */
|
/* '#!' is ignored at beginning to allow C scripts. */
|
||||||
goto ignore;
|
goto ignore;
|
||||||
tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
|
tcc_warning("ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
|
||||||
ignore:
|
ignore:
|
||||||
skip_to_eol(0);
|
skip_to_eol(0);
|
||||||
goto the_end;
|
goto the_end;
|
||||||
@ -2475,7 +2475,7 @@ static void parse_number(const char *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unsigned long long n, n1;
|
unsigned long long n = 0, n1 = 0;
|
||||||
int lcount, ucount, ov = 0;
|
int lcount, ucount, ov = 0;
|
||||||
const char *p1;
|
const char *p1;
|
||||||
|
|
||||||
@ -2486,7 +2486,6 @@ static void parse_number(const char *p)
|
|||||||
b = 8;
|
b = 8;
|
||||||
q++;
|
q++;
|
||||||
}
|
}
|
||||||
n = 0;
|
|
||||||
while(1) {
|
while(1) {
|
||||||
t = *q++;
|
t = *q++;
|
||||||
/* no need for checks except for base 10 / 8 errors */
|
/* no need for checks except for base 10 / 8 errors */
|
||||||
@ -2500,11 +2499,13 @@ static void parse_number(const char *p)
|
|||||||
t = t - '0';
|
t = t - '0';
|
||||||
if (t >= b)
|
if (t >= b)
|
||||||
tcc_error("invalid digit");
|
tcc_error("invalid digit");
|
||||||
n1 = n;
|
|
||||||
n = n * b + t;
|
n = n * b + t;
|
||||||
/* detect overflow */
|
if (!ov)
|
||||||
if (n1 >= 0x1000000000000000ULL && n / b != n1)
|
/* detect overflow */
|
||||||
ov = 1;
|
if (n1 >= 0x1000000000000000ULL && n / b != n1)
|
||||||
|
ov = 1;
|
||||||
|
else
|
||||||
|
n1 = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine the characteristics (unsigned and/or 64bit) the type of
|
/* Determine the characteristics (unsigned and/or 64bit) the type of
|
||||||
@ -2554,7 +2555,26 @@ static void parse_number(const char *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ov)
|
if (ov)
|
||||||
tcc_warning("integer constant overflow");
|
/* Give a warning with values in case of an overflow. This helps to
|
||||||
|
spot the 0 too much in 0x8000'0000'0000'0000'0. It may even be
|
||||||
|
better to use a 0x8000'0000'0000'0000 from n1 instead of a 0 from
|
||||||
|
n after the overflow. This is at least undefined behavior.
|
||||||
|
The C99 to C23 standards state:
|
||||||
|
"Each constant shall have a type and the value of a constant
|
||||||
|
shall be in the range of representable values for its type."
|
||||||
|
"If an integer constant cannot be represented by any type ...,
|
||||||
|
then the integer constant has no type."
|
||||||
|
The C++ standards state:
|
||||||
|
"A program is ill-formed if one of its translation units contains
|
||||||
|
an integer-literal that cannot be represented by any of the
|
||||||
|
allowed types." */
|
||||||
|
tcc_warning(
|
||||||
|
b == 8
|
||||||
|
? "integer constant overflow, using %#llo; did you mean %#llo?"
|
||||||
|
: b == 10
|
||||||
|
? "integer constant overflow, using %llu, did you mean %llu?"
|
||||||
|
: "integer constant overflow, using %#llx; did you mean %#llx?",
|
||||||
|
n, n1);
|
||||||
|
|
||||||
tok = TOK_CINT;
|
tok = TOK_CINT;
|
||||||
if (lcount) {
|
if (lcount) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user