public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: David Edelsohn <dje@watson.ibm.com>
To: Janis Johnson <janis187@us.ibm.com>,
	Mark Mitchell <mark@codesourcery.com>
Cc: Andreas Schwab <schwab@suse.de>,
	Aldy Hernandez <aldyh@redhat.com>,
	gcc@gcc.gnu.org
Subject: Re: ia64 linux doesn't bootstrap
Date: Fri, 18 Oct 2002 16:05:00 -0000	[thread overview]
Message-ID: <200210182002.QAA29492@makai.watson.ibm.com> (raw)
In-Reply-To: Message from David Edelsohn <dje@watson.ibm.com>  of "Fri, 18 Oct 2002 12:48:33 EDT." <200210181648.MAA25342@makai.watson.ibm.com>

	Tighten your seatbelt, the AIX failure is another case where the C
and C++ front-ends are not consistent with respect to the state of a DECL
after warnings.  I am not sure which one is right.

	The testcase in g++.dg/break/bitfield7_y.C creates a bitfield that
is too wide:

union U {
  int i: 4096;
};

and accesses it:

void bitfield7_y (U* u)
{
  if (u[0].i != 7)
    abort ();
  if (u[1].i != 8)
    abort ();

This is based on g++.dg/abi/bitfield7.C which declares the union and looks
for both the ABI warning and the "width exceeds type" warning without
accessing a variable of that type.

	The C++ testcase ICEs while the equivalent C testcase does not.

	c-decl.c:finish_struct() ignores out of range field widths -- not
only warning but leaving a number of DECL fields undefined:

          if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
            error_with_decl (x, "negative width in bit-field `%s'");
          else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
            pedwarn_with_decl (x, "width of `%s' exceeds its type");	<***
          else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
            error_with_decl (x, "zero width for bit-field `%s'");
          else
	    {
	      ...

              DECL_SIZE (x) = bitsize_int (width);
              DECL_BIT_FIELD (x) = 1;
              SET_DECL_C_BIT_FIELD (x);
	      ...
	    }

	cp/class.c sometimes leaves the DECL fields undefined (by setting
error_mark_node) and sometimes proceeds with assigning the DECL fields, as
in the case of the "width exceeds type" warning:

      if (TREE_CODE (w) != INTEGER_CST)
        {
          cp_error_at ("bit-field `%D' width not an integer constant",
                       field);
          w = error_mark_node;
        }
      else if (tree_int_cst_sgn (w) < 0)
        {
          cp_error_at ("negative width in bit-field `%D'", field);
          w = error_mark_node;
        }
      else if (integer_zerop (w) && DECL_NAME (field) != 0)
        {
          cp_error_at ("zero width for bit-field `%D'", field);
          w = error_mark_node;
        }
      else if (compare_tree_int (w, TYPE_PRECISION (type)) > 0
               && TREE_CODE (type) != ENUMERAL_TYPE
               && TREE_CODE (type) != BOOLEAN_TYPE)
        cp_warning_at ("width of `%D' exceeds its type", field);	<***
      else if (TREE_CODE (type) == ENUMERAL_TYPE
               && (0 > compare_tree_int (w,
                                         min_precision (TYPE_MIN_VALUE (type),
                                                        TREE_UNSIGNED (type)))
                   ||  0 > compare_tree_int (w,
                                             min_precision
                                             (TYPE_MAX_VALUE (type),
                                              TREE_UNSIGNED (type)))))
        cp_warning_at ("`%D' is too small to hold all values of `%#T'",
                       field, type);
    }

...

  if (w != error_mark_node)
    {
      DECL_SIZE (field) = convert (bitsizetype, w);
      DECL_BIT_FIELD (field) = 1;
      ...
    }


To summarize the situation so far, a bitfield width exceeding the type
size will leave DECL_BIT_FIELD unset for the C front-end but will set it
for the C++ front-end.

	Later in expr.c:expand_expr(), get_inner_reference() will
calculate the mode of the field as the mode of the outer expression for C
(because DECL_BIT_FIELD is false) and VOIDmode for C++ (because
DECL_BIT_FIELD is true).

	For C++, the VOIDmode means the field is an unaligned field in an
aligned union.  This invokes extract_bit_field() which calculates a crazy
bit offset handed to operand_subword() and simplify_gen_subreg() which
eventually ICEs.  For C, the sane outer mode skips the extract_bit_field()
call and accesses the "component" directly.

	I do not know whether C++ should behave like C and not set
DECL_BIT_FIELD.  However, if DECL_BIT_FIELD should not be set for width
exceeding type then why should it ever be set?  The non-VOIDmode case in
expand_expr() using adjust_address() and convert_move() appears to have
succeeded even though the inner mode was not aligned.

The various possibilities seem to be:

cp/class.c should not set DECL_BIT_FIELD when width exceeds type.

OR

c-decl.c should set DECL_BIT_FIELD when width exceeds type.

	If DECL_BIT_FIELD is set when the width exceeds the type, there
needs to be some other change in the backend to prevent the ICE.

get_inner_reference() always should return the outer mode?  expand_expr()
should use adjust_address() and convert_move() even when the inner mode is
VOIDmode?

	I do not know which behavior is correct other than GCC should not
ICE.

Thanks, David

  reply	other threads:[~2002-10-18 20:03 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-10-18  4:53 Aldy Hernandez
2002-10-18  7:33 ` Tim Prince
2002-10-18 11:49   ` Jim Wilson
2002-10-19  7:39     ` Tim Prince
2002-10-22 15:23       ` Jim Wilson
2002-10-24  4:43         ` tprinceusa
2002-10-18  8:18 ` Andreas Schwab
2002-10-18 12:49   ` Janis Johnson
2002-10-18 12:53     ` David Edelsohn
2002-10-18 16:05       ` David Edelsohn [this message]
2002-10-18 17:04         ` Mark Mitchell
2002-10-18 17:12           ` Janis Johnson
2002-10-19  1:09           ` David Edelsohn
2002-10-21  3:28             ` Mark Mitchell
2002-10-21 18:03               ` Jim Wilson
2002-10-21 19:49               ` Janis Johnson
2002-10-20  6:16     ` Andreas Schwab
2002-10-20  9:43       ` Janis Johnson
2002-10-18 13:01   ` Aldy Hernandez
2002-10-21 20:34 Ulrich Weigand
2002-10-21 23:35 ` David Edelsohn
2002-10-22 10:43   ` Ulrich Weigand

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=200210182002.QAA29492@makai.watson.ibm.com \
    --to=dje@watson.ibm.com \
    --cc=aldyh@redhat.com \
    --cc=gcc@gcc.gnu.org \
    --cc=janis187@us.ibm.com \
    --cc=mark@codesourcery.com \
    --cc=schwab@suse.de \
    /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: link
Be 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).