From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8258 invoked by alias); 18 Oct 2002 20:03:37 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 8249 invoked from network); 18 Oct 2002 20:03:36 -0000 Received: from unknown (HELO igw3.watson.ibm.com) (198.81.209.18) by sources.redhat.com with SMTP; 18 Oct 2002 20:03:36 -0000 Received: from sp1n293en1.watson.ibm.com (sp1n293en1.watson.ibm.com [9.2.112.57]) by igw3.watson.ibm.com (8.11.4/8.11.4) with ESMTP id g9IK2w821434; Fri, 18 Oct 2002 16:02:58 -0400 Received: from makai.watson.ibm.com (makai.watson.ibm.com [9.2.216.144]) by sp1n293en1.watson.ibm.com (8.11.4/8.11.4) with ESMTP id g9IK2wV49156; Fri, 18 Oct 2002 16:02:58 -0400 Received: from watson.ibm.com (localhost [127.0.0.1]) by makai.watson.ibm.com (AIX4.3/8.9.3/8.9.3/09-18-2002) with ESMTP id QAA29492; Fri, 18 Oct 2002 16:02:53 -0400 Message-Id: <200210182002.QAA29492@makai.watson.ibm.com> To: Janis Johnson , Mark Mitchell cc: Andreas Schwab , Aldy Hernandez , gcc@gcc.gnu.org Subject: Re: ia64 linux doesn't bootstrap In-Reply-To: Message from David Edelsohn of "Fri, 18 Oct 2002 12:48:33 EDT." <200210181648.MAA25342@makai.watson.ibm.com> Date: Fri, 18 Oct 2002 16:05:00 -0000 From: David Edelsohn X-SW-Source: 2002-10/txt/msg01144.txt.bz2 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