public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* 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

* 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

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 --
2002-04-26  4:59 c++/4588: bogus warning concerning bit field limits nathan
  -- strict thread matches above, loose matches on Subject: below --
2003-01-01 21:33 neroden
2001-10-17  0:56 ben

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).