public inbox for gcc-prs@sourceware.org help / color / mirror / Atom feed
From: ben@666.com To: gcc-gnats@gcc.gnu.org Cc: martin@xemacs.org, ben@666.com Subject: c++/4588: bogus warning concerning bit field limits Date: Wed, 17 Oct 2001 00:56:00 -0000 [thread overview] Message-ID: <20011017075346.10920.qmail@sourceware.cygnus.com> (raw) >Number: 4588 >Category: c++ >Synopsis: bogus warning concerning bit field limits >Confidential: no >Severity: non-critical >Priority: medium >Responsible: unassigned >State: open >Class: sw-bug >Submitter-Id: net >Arrival-Date: Wed Oct 17 00:56:01 PDT 2001 >Closed-Date: >Last-Modified: >Originator: ben@666.com >Release: 2.95.3-5 >Organization: >Environment: Cygwin >Description: i get the following warnings: /src/xemacs/mule/src/alloc.c: In function `void sledgehammer_check_ascii_begin(L isp_Object)': /src/xemacs/mule/src/alloc.c:1846: warning: comparison is always 0 due to width of bitfield but this is bogus, as the code shows. here is the function mentioned: [line 1846 is second from bottom, and indicated with an arrow like <=========== ] void sledgehammer_check_ascii_begin (Lisp_Object str) { int i; for (i = 0; i < XSTRING_LENGTH (str); i++) { if (!BYTE_ASCII_P (XSTRING_BYTE (str, i))) break; } assert (i == (int) XSTRING_ASCII_BEGIN (str) || (i > MAX_STRING_ASCII_BEGIN && XSTRING_ASCII_BEGIN (str) == MAX_STRING_ASCII_BEGIN)); <========== } the various structures and macros look like this: struct Lisp_String { union { struct lrecord_header lheader; struct { /* WARNING: Everything before ascii_begin must agree exactly with struct lrecord_header */ unsigned int type :8; unsigned int mark :1; unsigned int c_readonly :1; unsigned int lisp_readonly :1; /* Number of chars at beginning of string that are one byte in length (BYTE_ASCII_P) */ unsigned int ascii_begin :21; } v; } u; Bytecount size; Bufbyte *data; Lisp_Object plist; }; typedef struct Lisp_String Lisp_String; typedef EMACS_INT Bytecount; [see below] typedef unsigned char Bufbyte; see below for Lisp_Object struct lrecord_header { /* index into lrecord_implementations_table[] */ unsigned int type :8; /* If `mark' is 0 after the GC mark phase, the object will be freed during the GC sweep phase. There are 2 ways that `mark' can be 1: - by being referenced from other objects during the GC mark phase - because it is permanently on, for c_readonly objects */ unsigned int mark :1; /* 1 if the object resides in logically read-only space, and does not reference other non-c_readonly objects. Invariant: if (c_readonly == 1), then (mark == 1 && lisp_readonly == 1) */ unsigned int c_readonly :1; /* 1 if the object is readonly from lisp */ unsigned int lisp_readonly :1; unsigned int unused :21; }; #define MAX_STRING_ASCII_BEGIN ((2 << 21) - 1) #define XSTRING_ASCII_BEGIN(s) string_ascii_begin (XSTRING (s)) #define string_ascii_begin(s) ((s)->u.v.ascii_begin + 0) #define XSTRING(x) XRECORD (x, string, Lisp_String) # define XRECORD(x, c_name, structtype) ((structtype *) XPNTR (x)) #define XPNTR(x) ((void *) XPNTRVAL(x)) NOTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Basically, a Lisp_Object is a [usually] 32-bit "tagged" integral type that can hold either a pointer, a 31-bit integer, or a few other things. XPNTR(x) just extracts the pointer. Most of the time we use `int' as the base type of Lisp_Object, and XPNTRVAL is just a no-op. However, we also have a version where the Lisp_Object is represented as a union, which allows for better type checking, so we use it for tests. This time, I was using this version, so I duly report the actual structures. But I seriously doubt it matters whether union or int is used, since the problem occurs after the string structure has been extracted from the Lisp_Object, and at that point we have nothing more to do with the Lisp_Object. Here is the int version for easy testing: typedef EMACS_INT Lisp_Object; #define XPNTRVAL(x) (x) /* This depends on Lisp_Type_Record == 0 */ #define EMACS_INT long Here is the grody union version that was actually used: typedef union Lisp_Object { /* if non-valbits are at lower addresses */ #ifdef WORDS_BIGENDIAN struct { EMACS_UINT val : VALBITS; enum_field (Lisp_Type) type : GCTYPEBITS; } gu; struct { signed EMACS_INT val : INT_VALBITS; unsigned int bits : INT_GCBITS; } s; struct { EMACS_UINT val : INT_VALBITS; unsigned int bits : INT_GCBITS; } u; #else /* non-valbits are at higher addresses */ struct { enum_field (Lisp_Type) type : GCTYPEBITS; EMACS_UINT val : VALBITS; } gu; struct { unsigned int bits : INT_GCBITS; signed EMACS_INT val : INT_VALBITS; } s; struct { unsigned int bits : INT_GCBITS; EMACS_UINT val : INT_VALBITS; } u; #endif /* non-valbits are at higher addresses */ EMACS_UINT ui; signed EMACS_INT i; /* This was formerly declared 'void *v' etc. but that causes GCC to accept any (yes, any) pointer as the argument of a function declared to accept a Lisp_Object. */ struct nosuchstruct *v; const struct nosuchstruct *cv; } Lisp_Object; # define XPNTRVAL(x) ((x).ui) #define GCMARKBITS 0 #define GCTYPEBITS 2 #define GCBITS 2 #define INT_GCBITS 1 #define INT_VALBITS (BITS_PER_EMACS_INT - INT_GCBITS) #define VALBITS (BITS_PER_EMACS_INT - GCBITS) #define EMACS_UINT unsigned long #define EMACS_INT is long #define BITS_PER_EMACS_INT 32 WORDS_BIGENDIAN not defined. So anyway, as you can see, ascii_begin in struct Lisp_String should be an unsigned int bitfield of 21 bits; therefore, its range is 0 .. 2^21 - 1. MAX_STRING_ASCII_BEGIN is 2^21 - 1, so it should be perfectly okay to compare a bitfield value to MAX_STRING_ASCII_BEGIN. >How-To-Repeat: >Fix: >Release-Note: >Audit-Trail: >Unformatted:
next reply other threads:[~2001-10-17 0:56 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2001-10-17 0:56 ben [this message] 2002-04-26 4:59 nathan 2003-01-01 21:33 neroden
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20011017075346.10920.qmail@sourceware.cygnus.com \ --to=ben@666.com \ --cc=gcc-gnats@gcc.gnu.org \ --cc=martin@xemacs.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).