This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: GCC turns &~ into | due to undefined bit-shift without warning
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Moritz Strübe <moritz dot struebe at redheads dot de>
- Cc: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>, Nicolai Steinkamp <nicolai dot steinkamp at redheads dot de>
- Date: Mon, 11 Mar 2019 10:14:49 +0100
- Subject: Re: GCC turns &~ into | due to undefined bit-shift without warning
- References: <4af9e251-f4c3-a5a4-e33d-fb8750c87e36@redheads.de>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Mon, Mar 11, 2019 at 08:49:30AM +0000, Moritz Strübe wrote:
> Considering that C11 6.5.7#3 ("If the value of the right operand
> is negative or is greater than or equal to the width of the promoted
> left operand, the behavior is undefined.") is not very widely known, as
> it "normally" just works, inverting the intent is quite unexpected.
>
> Is there any option that would have helped me with this?
You could build with -fsanitize=undefined, that would tell you at runtime you
have undefined behavior in your code (if the SingleDiff has bit ever 0x20
set).
The fact that negative or >= bit precision shifts are UB is widely known,
and even if it wouldn't, for the compiler all the UBs are just UBs, the
compiler optimizes on the assumption that UB does not happen, so when it
sees 32-bit int << (x & 32), it can assume x must be 0 at that point,
anything else is UB.
GCC has warnings for the simple cases, where one uses negative or too large
constant shift, warning in cases like you have would be a false positive for
many people, there is nothing wrong with that (if x & 32 always results in
0).
Jakub