[cfe-commits] PATCH: Warn on left shifts which overflow, even when not due to the RHS

Chandler Carruth chandlerc at google.com
Mon Feb 21 00:48:51 PST 2011


On Mon, Feb 21, 2011 at 12:41 AM, Chandler Carruth <chandlerc at google.com>wrote:

> On Mon, Feb 21, 2011 at 12:35 AM, Abramo Bagnara <abramo.bagnara at gmail.com
> > wrote:
>
>> Il <21%2F02%2F2011%2005>21/02/2011 05:21, Chandler Carruth ha scritto:
>> > This patch (originally by Oleg Slezberg) implements a warning that would
>> > have caught several major bugs we found, so I'm pretty excited about it.
>> > The fundamental premise is that the user writes code as follows:
>> >
>> > int64_t i = 10 << 30;
>> >
>> > The user thinks this is a nice 10 gig constant for their disk size. The
>> > compiler thinks this is -2 gigs. Oops.
>> >
>> > As it turns out, this is technically undefined behavior, and so it seems
>> > doubly good to warn about it when we see it. The warning has a special
>> > case though. It still provides a warning for the expression (1 << 31)
>> > because it's undefined behavior to do this, but that warning is by
>> > default ignored. If the value is converted to an unsigned integer, it
>> > will have the intended value as all the bits did in fact get set. It
>> > seems much less important to warn about this case. The result looks
>> > something like:
>>
>> I don't know if this is relevant for your design, but it should be noted
>> that according to C++ standard (and differently from C99 standard) the
>> excess left shift of signed integers is not undefined behaviour, but it
>> is implementation dependent (see C++03 5.8p2), i.e. as the shift should
>> be implemented as a logical shift the result depends from integer
>> representation (C++ allows 1's complement, 2's complement and signed
>> magnitude).
>>
>
> Where are you seeing this? According to my copy of the C++03 standard,
> 5.8p2 doesn't specify any behavior for signed integers, making this most
> likely undefined behavior due to omission. You might read 5p5 as being
> relevant, but in that case this is actually ill formed, not just undefined
> behavior.
>
> The C++0x drafts specify explicitly that this behavior is undefined for
> signed integers in 5.8p2, making it my strong suspicion that it was intended
> to be undefined behavior all along, and merely omitted previously. I've not
> read the C standard thoroughly in this area, so I'm not commenting on its
> requirements, but I'd not expect them to be different here.
>

Having now read the C99 standard, it has the exact same wording as C++0x
drafts (I suppose that the 0x drafts are based on the C99 wording). The C89
standard is silent on the issue (likely leading to the C++03 silence). I
don't think there is any inconsistency between the languages, or backwards
incompatibility here. I think this restriction has merely been clarified
over time.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20110221/0ac72eae/attachment.html>


More information about the cfe-commits mailing list