From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.osdl.org (smtp.osdl.org [65.172.181.25]) (using TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (Client CN "smtp.osdl.org", Issuer "OSDL Hostmaster" (not verified)) by ozlabs.org (Postfix) with ESMTP id 3E33667BB6 for ; Sat, 2 Dec 2006 02:30:24 +1100 (EST) Date: Fri, 1 Dec 2006 07:30:18 -0800 (PST) From: Linus Torvalds To: Geert Uytterhoeven Subject: Re: cast truncates bits from constant value (8000000000000000 becomes 0) In-Reply-To: Message-ID: References: <4563D00D.4010704@am.sony.com> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Cc: Linux/PPC Development , linux-sparse@vger.kernel.org List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , On Fri, 1 Dec 2006, Geert Uytterhoeven wrote: > > On Tue, 21 Nov 2006, Geoff Levand wrote: > > +enum ps3_vendor_id { > > + PS3_VENDOR_ID_NONE = 0, > > + PS3_VENDOR_ID_SONY = 0x8000000000000000UL, > > +}; > > I've just ran `make C=1' (PPC in 64-bit mode, and sparse is called with -m64), > and noticed that sparse (cloned from > git://git.kernel.org/pub/scm/devel/sparse/sparse.git a few minutes ago) > complains about the second value with: > > | warning: cast truncates bits from constant value (8000000000000000 becomes 0) > > Section 6.7.2.2.4 of C99 says: > > | Each enumerated type shall be compatible with char, a signed integer type, or > | an unsigned integer type. The choice of type is implementation-defined, but > | shall be capable of representing the values of all the members of the > | enumeration. > > The code snippet > > | u64 x = PS3_VENDOR_ID_SONY; > | printk("PS3_VENDOR_ID_SONY = %lu\n", x); > > does print the expected (i.e. non-zero) result. > > Hence this looks like a bug in sparse. It's really a bug in gcc, but it's documented, so it's a "feature". Gcc allows large enums, but does so in such a strange manner that it's totally hopeless to catch problems. Also, putting a value that is larger than "unsigned int" into an enum is really setting yourself up for bugs and not even guaranteed to work for standard C, so sparse takes a dim view of it and just says that enums are limited in size to "int" or "unsigned int". You can either ignore that warning or just use a #define. Linus