https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113852

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2024-02-09

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
If a1 and a2 are const then GCC also notices the undefined overflow:

<source>: In function 'int main()':
<source>:18:13: warning: integer overflow in expression of type 'int' results
in '-131071' [-Woverflow]
   18 |     if ((a1 * a2) > a3) {
      |          ~~~^~~~
<source>:18:19: warning: comparison of integer expressions of different
signedness: 'int' and 'uint64_t' {aka 'long unsigned int'} [-Wsign-compare]
   18 |     if ((a1 * a2) > a3) {
      |         ~~~~~~~~~~^~~~

I don't know why the -Wsign-compare warning is only given when we've detected
the overflow. The types are always the same, whether the values are known to
overflow or not.

I assume what's happening is that GCC assumes integer promotion from uint16_t
to int is value preserving and so we get two positive values, and therefore
comparison with an unsigned value is fine - there are no negative values
involved and so it doesn't matter that we're comparing int with unsigned long.
But of course that's not true here. We have two positive ints but their product
overflows to produce a negative int. I guess we're also assuming no overflow
happens, because that would be undefined and we assume no UB.

When the values are constant we can tell the overflow happens, and no longer
assume it doesn't happen.

Reply via email to