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

            Bug ID: 67602
           Summary: unsigned left-shift overflow should not be undefined
                    in c++
           Product: gcc
           Version: 4.8.5
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: huntting at glarp dot com
  Target Milestone: ---

Created attachment 36343
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36343&action=edit
example.cc

For an unsigned E1, E1<<E2 should be equal to E1*2^E2 mod 2^N (where N is the
size of E1). There is no restriction on E2 except that it must be non-negative.
Hence ~0U<<32 should always be 0 if ints are 32bits.

Unfortunately, when I compile the attached example.cc on amd64 with -O0, I get
this:

                  sizeof(0ULL) = 8
                         ~0ULL = 0xffffffffffffffff
     ~0ULL << (8*sizeof(0ULL)) = 0xffffffffffffffff
  ~(~0ULL << (8*sizeof(0ULL))) = 0
                    sizeof(0U) = 4
                           ~0U = 0xffffffff
         ~0U << (8*sizeof(0U)) = 0xffffffff
      ~(~0U << (8*sizeof(0U))) = 0

Curiously, enabling -O1 fixes the problem. I have also seen this behavior when
the expression is not known at compile time but I've not tested under various
-O levels in that case.

It should be noted that the C standard appears to allow for undefined behavior
when E2>=N.

Reply via email to