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

            Bug ID: 77891
           Summary: Signed overflow sanitizer doesn't catch multiplication
                    overflows due to promotion
           Product: gcc
           Version: 6.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: myriachan at gmail dot com
                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
  Target Milestone: ---

-fsanitize=signed-integer-overflow doesn't catch multiplication overflows that
occur in signed types due to promotion rules.  This can happen when you use an
unsigned type that is exactly half the width of "signed int".  That's usually
"unsigned short".

The following should generate two runtime errors when compiled with
-fsanitize=signed-integer-overflow, but instead only one error occurs:

#include <cstdio>

int main()
{
        std::printf("unsigned short\n");
        std::fflush(stdout);
        unsigned short x = 65535;
        x *= x;

        std::printf("signed int\n");
        std::fflush(stdout);
        signed int y = 65535;
        y *= y;

        return 0;
}

myria@machine:~/tests$ g++ -m64 -std=gnu++11 -Wstrict-overflow -ftrapv
-fstrict-overflow -fsanitize=signed-integer-overflow overflow.cpp -lpthread
-ldl -o overflow64
myria@machine:~/tests$ ./overflow64
unsigned short
signed int
overflow.cpp:13:15: runtime error: signed integer overflow: 65535 * 65535
cannot be represented in type 'int'

Clang does pick up the overflow, though:

myria@machine:~/tests$ clang++-3.8 -m64 -std=gnu++11 -stdlib=libc++
-fsanitize=signed-integer-overflow overflow.cpp -o overflow64
myria@machine:~/tests$ ./overflow64
unsigned short
overflow.cpp:8:11: runtime error: signed integer overflow: 65535 * 65535 cannot
be represented in type 'int'
signed int
overflow.cpp:13:11: runtime error: signed integer overflow: 65535 * 65535
cannot be represented in type 'int'

Reply via email to