This is the mail archive of the
mailing list for the GCC project.
Re: Unsure about a new warning in mainline
Hi Manuel and Paolo,
On Sun, January 14, 2007 3:59 pm, Paolo Carlini wrote:
>>> By the way, "new" also wrt current 4_2-branch, in the sense that the
>>> latter doesn't emit *any* overflow warning for the snippet in 30465,
>>> with explicit -Wconversion too...
I think I can explain everything. The first issue, is that although the C
front-end has issued these warnings for years, a recent change to the C++
front-end means that it now emits them too. This is why Paolo hadn't seen
them before, but from the C/middle-end perspective the code is unchanged.
The second issue is that there are two different overflow related
warnings. The first warning indicates that an overflow has occurred in an
expression, and the second is that the overflowed result is used in a
to be a compile-time constant. Apparently, the latter is more serious
than the first, as an expression that overflows isn't considered a
"constant" according to the/some standard.
Manuel's confusion here is that recent changes mean that we now only emit
one warning of the first kind in an expression. Previously, for suitably
nasty expressions we'd generate multiple such warnings. As for example,
in "- - - - - - INT_MIN". Formerly, we'd issue one "overflow warning" per
negation. However, we still continue to generate one warning for any
overflow in an expression, and another if the result of that expression is
used in a context required to be a constant.
Hopefully, these differences can be seen by compiling the problematic code
given in PR 30465 with "gcc" then with "g++".
I agree with Paolo that this is a change for C++, and should at least be
documented in changes.html, and probably be tweaked to avoid warning in
system headers. However, it's also odd that in this respect C has had
stricter/better diagnostics that C++ for some time.
Specifically, for PR 30465 "((T)1 << 31) - 1" is potentially undefined
when T is a 32-bit signed type, but well-defined if T is unsigned or
wider than 32-bits.
I hope this helps.