Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Nov 2013 12:29:39 -0800
From:      Peter Wemm <peter@wemm.org>
To:        freebsd-arch@freebsd.org
Subject:   Re: 1 << 31 and related issues
Message-ID:  <5293B333.9070804@wemm.org>
In-Reply-To: <CAF6rxgm9Q9ckhKR75sKRjAmebGGNM_jpDjiUqeUd%2B=WbCf6TRw@mail.gmail.com>
References:  <CAF6rxgm9Q9ckhKR75sKRjAmebGGNM_jpDjiUqeUd%2B=WbCf6TRw@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On 11/25/13, 11:48 AM, Eitan Adler wrote:
> There are a few cases in FreeBSD where the expression (1 << 31) is used.
> 
> However this produces undefined behavior as '1' is of type int.  (see
> 6.4.4p5: The type of an unmarked integer constant is the first of the
> following list in which its value can be represented: int, long int,
> long long int).  The shift of 31 is illegal (see 6.5.7p4) if the size
> of an int is 32.  The same issue arises with 2 << 30 and 3 << 30.
> 
> I have been working on fixing this issue in a few different projects.
> The correct fix here is to use 1U as the literal instead.  adrian@ has
> advocated for the macros BIT32(bit) and BIT64(bit) which I would also
> support.
> 
> I have patches which fix the issue by using 1U in these cases.  I did
> not change non-broken cases.  I also did not change contributed code.
> 
> An incomplete listing of the issues available here:
> http://people.freebsd.org/~eadler/files/1..31.txt
> 

I find it particularly enjoyable to see things like this in crypto code:

crypto/heimdal/lib/hx509/ref/pkcs11.h:#define CKF_EXTENSION		((unsigned
long) (1 << 31))
crypto/openssh/pkcs11.h:#define CKO_VENDOR_DEFINED	((unsigned long) (1
<< 31))

FWIW,  This came up in both ia64 and amd64 early days.  Most of this was
hunted down in the kernel back then.  Obviously some has crept back in,
or is in contrib or driver code.

The problem there is bigger though.  On 64 bit machines, 1u << N tends
to get used where N > 32 as well.  1u << 33 is an overflow and doesn't
extend up into the 33rd bit.  We changed most uses to 1ul << N where
this was likely.  This did predate the BIT* macros you referenced.

FWIW2: we had an acpi bug with 1 << 31 way back in the early days.  Back
then, the compiler generated different code when compiled with -O2 vs
not and 1<<31 had different values depending on compile time switches.

-Peter




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5293B333.9070804>