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
On 11/03/2019 12:24, Vincent Lefevre wrote:
> On 2019-03-11 11:06:37 +0000, Moritz Strübe wrote:
>> On 11.03.2019 at 10:14 Jakub Jelinek wrote:
>>> The fact that negative or >= bit precision shifts are UB is widely known,
> [...]
>
> And even in the case where the compiler maps the shift directly to
> the asm shift (without optimizations), the behavior may depend on
> the processor.
>
>> Thanks for that explanation. None the less, a compile time warning
>> would be nice.
>
> It already does by default:
>
> -Wshift-count-negative
> Warn if shift count is negative. This warning is enabled
> by default.
>
> -Wshift-count-overflow
> Warn if shift count >= width of type. This warning is
> enabled by default.
>
> Of course, if the compiler cannot guess that there will be such
> an issue, it will not emit the warning. You certainly don't want
> a warning for each non-trivial shift just because the compiler
> cannot know whether the constraint on the shift count will be
> satisfied.
>
While the compiler clearly can't give a warning on calculated shifts
without massive amounts of false positives, it is able to give warnings
when there is a shift by a compile-time known constant value that is
invalid. In the case of the OP's test function, inlining and constant
propagation means that the shift value /is/ known to the compiler - it
uses it for optimisation (in this case, it uses the undefined behaviour
to "simplify" the calculations).
Am I right in thinking that this is because the pass that checks the
shift sizes for warnings here comes before the relevant inlining or
constant propagation passes? And if so, would it be possible to change
the ordering here?
Perhaps it would be possible to have a warning for when the compiler
optimises based on undefined behaviour, when the undefined behaviour
comes from values that are known to the compiler at compile time? (When
the values are not known at compile time, optimising on the assumption
that the undefined behaviour doesn't happen is fair enough, and you
can't warn there without lots of false positives.)