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

            Bug ID: 79877
           Summary: -Wstrict-overflow false positive or misunderstanding?
           Product: gcc
           Version: 7.0.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: s-beyer at gmx dot net
  Target Milestone: ---

Hi,

I have the following code:

----
$ cat foo.cc
#include <iostream>

static int strict_overflow_warning(int bitmask) {
        int max = -1;
        for (int i = 31; i > max; i--) {
                if (bitmask & (1 << i)) {
                        max = i;
                }
        }
        return max;
}

static int no_strict_overflow_warning(int bitmask) {
        int max = -1;
        for (int i = 31; i >= 0; i--) {
                if (bitmask & (1 << i)) {
                        max = i;
                        break;
                }
        }
        return max;
}

int main(int argc, char *argv[]) {
        std::cout << strict_overflow_warning(argc) << std::endl;
        std::cout << no_strict_overflow_warning(argc) << std::endl;

        std::cout << strict_overflow_warning(0) << std::endl;
        std::cout << no_strict_overflow_warning(0) << std::endl;

        std::cout << strict_overflow_warning(-argc) << std::endl;
        std::cout << no_strict_overflow_warning(-argc) << std::endl;
        return 0;
}
----

I get the following output (depending on g++ version and -O flag):

----
$ g++-7 -O3 -Wstrict-overflow foo.cc && ./a.out 2 3 4 5 6 7 8
foo.cc: In function ‘int main(int, char**)’:
foo.cc:5:21: warning: assuming signed overflow does not occur when assuming
that (X - c) <= X is always true [-Wstrict-overflow]
  for (int i = 31; i > max; i--) {
                   ~~^~~~~
foo.cc:5:21: warning: assuming signed overflow does not occur when assuming
that (X - c) <= X is always true [-Wstrict-overflow]
  for (int i = 31; i > max; i--) {
                   ~~^~~~~
3
3
-1
-1
31
31
$ g++-7 -O2 -Wstrict-overflow foo.cc && ./a.out 2 3 4 5 6 7 8
3
3
-1
-1
31
31
$ g++-6 -O3 -Wstrict-overflow foo.cc && ./a.out 2 3 4 5 6 7 8
3
3
-1
-1
31
31
----

The two functions should be semantically equivalent (as the output
indicates). Why does the version using i > max (instead of using i >= 0
and the break) show me the strict-overflow warning?

Thank you,
  Stephan

Reply via email to