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

            Bug ID: 87837
           Summary: -O2 -fsanitize=signed-integer-overflow misses
                    overflows on x86-64
           Product: gcc
           Version: 8.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: eggert at cs dot ucla.edu
                CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
                    jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at 
gcc dot gnu.org
  Target Milestone: ---

In GCC 8, -O2 -fsanitize=signed-integer-overflow (and -fsanitize=undefined) is
missing signed integer overflows. GCC 7 caught them so this is a regression. I
observed the problem with GCC 8.2.1 20181011 (Red Hat 8.2.1-4) on x86-64.
Consider this function in the file testovf.c:

_Bool
testovf (long n)
{
  return n + 9223372036854775807 < n;
}

Compile it with:

gcc -O2 -S -fsanitize=signed-integer-overflow testovf.c

With GCC 7.3.0, an overflow will be detected at runtime if one passes a
positive value to 'testovf', but with GCC 8.2.1 no overflow is detected. This
is because GCC 7.3.0 generates overflow-checking code (e.g., "addq %rdx, %rdp;
jo .L6") whereas GCC 8.2.1 merely generates this:

testovf:
        xorl    %eax, %eax
        ret

Apparently GCC 8 is optimizing away the overflow test on the ground that if
overflow occurs, behavior is undefined so the generated code can do anything.
But when -fsanitize=signed-integer-overflow is used, that's not correct: the
user wants overflows to be diagnosed, not to be optimized away. That is, when
-fsanitize=signed-integer-overflow is used, behavior is not undefined when
signed integer overflow occurs (it is well-defined to trap), so these
optimizations should be inhibited.

Reply via email to