public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "eggert at cs dot ucla.edu" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c/107116] New: -Woverflow false alarm in unreachable code
Date: Sat, 01 Oct 2022 22:09:17 +0000	[thread overview]
Message-ID: <bug-107116-4@http.gcc.gnu.org/bugzilla/> (raw)

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);
      |          ^~~~~~~~~~~~~~~~~~
$

             reply	other threads:[~2022-10-01 22:09 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-01 22:09 eggert at cs dot ucla.edu [this message]
2022-10-01 22:13 ` [Bug c/107116] " pinskia at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-107116-4@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).