public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/107116] New: -Woverflow false alarm in unreachable code
@ 2022-10-01 22:09 eggert at cs dot ucla.edu
  2022-10-01 22:13 ` [Bug c/107116] " pinskia at gcc dot gnu.org
  0 siblings, 1 reply; 2+ messages in thread
From: eggert at cs dot ucla.edu @ 2022-10-01 22:09 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 107116
           Summary: -Woverflow false alarm in unreachable code
           Product: gcc
           Version: 12.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

This bug is following up on a bug reported against coreutils
<https://bugs.gnu.org/58163>. In the coreutils bug report, a build failed
because of a false alarm generated by GCC. I simplified the source and came up
with two different GCC test cases, shown in the shell transcript below. I
generated this transcript on Fedora 36 x86-64, which has gcc (GCC) 12.2.1
20220819 (Red Hat 12.2.1-2).

In the first (shorter) test case v.i, gcc -O2 -Woverflow incorrectly complains
about INT_MAX + 1900 in code that is unreachable because YEAR must be both
negative and nonnegative to reach the expression, which is impossible.

The second (longer) test case t.c has the same false alarm; I'm including it
mostly to give you a feel for the false alarm's context in coreutils, which is
even more complicated than the second test case.


$ cat v.i
enum { INT_MAX = 0x7fffffff };
_Bool
to_tm_year (long year)
{
  return
    (year < 0
     && (year < 0
         ? year + 1900 < 0
         : INT_MAX + 1900 < year));
}
$ gcc -O2 -S -Woverflow v.i
v.i: In function ‘to_tm_year’:
v.i:9:20: warning: integer overflow in expression of type ‘int’ results in
‘-2147481749’ [-Woverflow]
    9 |          : INT_MAX + 1900 < year));
      |                    ^
$ cat t.c
enum { INT_MAX = 0x7fffffff, INT_MIN = -1 - INT_MAX };
#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))
#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))
#define _GL_EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)
#define _GL_INT_SUBTRACT_RANGE_OVERFLOW(a, b, tmin, tmax) \
  (((a) < 0) == ((b) < 0) \
   ? ((a) < (b) \
      ? !(tmin) || -1 - (tmin) < (b) - (a) - 1 \
      : (tmax) < (a) - (b)) \
   : (a) < 0 \
   ? ((!_GL_EXPR_SIGNED (_GL_INT_CONVERT ((a) - (tmin), b)) && (a) - (tmin) <
0) \
      || (a) - (tmin) < (b)) \
   : ((! (_GL_EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \
          && _GL_EXPR_SIGNED (_GL_INT_CONVERT ((tmax) + (b), a))) \
       && (tmax) <= -1 - (b)) \
      || (tmax) + (b) < (a)))
#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \
  ((t) ((ut) (a) op (ut) (b)))
#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \
  (overflow (a, b, tmin, tmax) \
   ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \
   : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0))
#define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \
       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
                        int, INT_MIN, INT_MAX)
#define _GL_INT_SUBTRACT_WRAPV(a, b, r) \
   _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW)
#define INT_SUBTRACT_WRAPV(a, b, r) _GL_INT_SUBTRACT_WRAPV (a, b, r)

_Bool
year_out_of_range (long year)
{
  int i;
  return INT_SUBTRACT_WRAPV (year, 1900, &i);
}
$ gcc -O2 -S -Woverflow t.c
t.c: In function ‘year_out_of_range’:
t.c:16:17: warning: integer overflow in expression of type ‘int’ results in
‘-2147481749’ [-Woverflow]
   16 |       || (tmax) + (b) < (a)))
      |                 ^
t.c:20:4: note: in expansion of macro ‘_GL_INT_SUBTRACT_RANGE_OVERFLOW’
   20 |   (overflow (a, b, tmin, tmax) \
      |    ^~~~~~~~
t.c:24:8: note: in expansion of macro ‘_GL_INT_OP_CALC’
   24 |        _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
      |        ^~~~~~~~~~~~~~~
t.c:27:4: note: in expansion of macro ‘_GL_INT_OP_WRAPV’
   27 |    _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW)
      |    ^~~~~~~~~~~~~~~~
t.c:28:37: note: in expansion of macro ‘_GL_INT_SUBTRACT_WRAPV’
   28 | #define INT_SUBTRACT_WRAPV(a, b, r) _GL_INT_SUBTRACT_WRAPV (a, b, r)
      |                                     ^~~~~~~~~~~~~~~~~~~~~~
t.c:34:10: note: in expansion of macro ‘INT_SUBTRACT_WRAPV’
   34 |   return INT_SUBTRACT_WRAPV (year, 1900, &i);
      |          ^~~~~~~~~~~~~~~~~~
$

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Bug c/107116] -Woverflow false alarm in unreachable code
  2022-10-01 22:09 [Bug c/107116] New: -Woverflow false alarm in unreachable code eggert at cs dot ucla.edu
@ 2022-10-01 22:13 ` pinskia at gcc dot gnu.org
  0 siblings, 0 replies; 2+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-10-01 22:13 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I thought there was a much older duplicate of this bug but I can't find it
right now.
When I saw older I mean under 1000.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-10-01 22:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-01 22:09 [Bug c/107116] New: -Woverflow false alarm in unreachable code eggert at cs dot ucla.edu
2022-10-01 22:13 ` [Bug c/107116] " pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).