public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* c++/4588: bogus warning concerning bit field limits
@ 2001-10-17 0:56 ben
0 siblings, 0 replies; 3+ messages in thread
From: ben @ 2001-10-17 0:56 UTC (permalink / raw)
To: gcc-gnats; +Cc: martin, ben
>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:
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: c++/4588: bogus warning concerning bit field limits
@ 2002-04-26 4:59 nathan
0 siblings, 0 replies; 3+ messages in thread
From: nathan @ 2002-04-26 4:59 UTC (permalink / raw)
To: ben, gcc-bugs, gcc-prs, martin, ben, nobody
Synopsis: bogus warning concerning bit field limits
State-Changed-From-To: open->feedback
State-Changed-By: nathan
State-Changed-When: Fri Apr 26 04:59:39 2002
State-Changed-Why:
please provide a self contained test case
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=4588
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: c++/4588: bogus warning concerning bit field limits
@ 2003-01-01 21:33 neroden
0 siblings, 0 replies; 3+ messages in thread
From: neroden @ 2003-01-01 21:33 UTC (permalink / raw)
To: ben, gcc-bugs, gcc-prs, martin, ben, nobody
Synopsis: bogus warning concerning bit field limits
State-Changed-From-To: feedback->closed
State-Changed-By: neroden
State-Changed-When: Wed Jan 1 13:33:25 2003
State-Changed-Why:
No feedback for 8 months. And it's just a warning, anyway.
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=4588
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2003-01-01 21:33 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-17 0:56 c++/4588: bogus warning concerning bit field limits ben
2002-04-26 4:59 nathan
2003-01-01 21:33 neroden
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).