From: Mark Mitchell Date: Wed, 1 Mar 2000 22:29:56 +0000 (+0000) Subject: stor-layout.c (layout_decl): Allow front-ends to explicitly set the DECL_SIZE for... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=33433751ff2ac9150ee5766b6f4d803fc04a6571;p=gcc.git stor-layout.c (layout_decl): Allow front-ends to explicitly set the DECL_SIZE for a FIELD_DECL. * stor-layout.c (layout_decl): Allow front-ends to explicitly set the DECL_SIZE for a FIELD_DECL. From-SVN: r32287 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d5de0e7211f..9ed3840623e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2000-03-01 Mark Mitchell + + * stor-layout.c (layout_decl): Allow front-ends to explicitly set + the DECL_SIZE for a FIELD_DECL. + 2000-03-01 Bruce Korb * fixinc/inclhack.tpl: remove unused symlinks diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 83a220abdf8..c1187b742e9 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -265,30 +265,17 @@ layout_decl (decl, known_align) { register tree type = TREE_TYPE (decl); register enum tree_code code = TREE_CODE (decl); - HOST_WIDE_INT spec_size = 0; if (code == CONST_DECL) return; - else if (code == FIELD_DECL) - { - if (DECL_SIZE (decl) != 0) - { - spec_size = TREE_INT_CST_LOW (DECL_SIZE (decl)); - DECL_SIZE (decl) = 0; - } - } else if (code != VAR_DECL && code != PARM_DECL && code != RESULT_DECL - && code != TYPE_DECL) + && code != TYPE_DECL && code != FIELD_DECL) abort (); if (type == error_mark_node) - { - type = void_type_node; - spec_size = 0; - } + type = void_type_node; /* Usually the size and mode come from the data type without change. */ - DECL_MODE (decl) = TYPE_MODE (type); TREE_UNSIGNED (decl) = TREE_UNSIGNED (type); if (DECL_SIZE (decl) == 0) @@ -296,14 +283,23 @@ layout_decl (decl, known_align) DECL_SIZE (decl) = TYPE_SIZE (type); DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type); } - - if (code == FIELD_DECL && DECL_BIT_FIELD (decl)) + else if (code == FIELD_DECL) { - if (spec_size == 0 && DECL_NAME (decl) != 0) + HOST_WIDE_INT spec_size; + + /* The front-end may set the explicit width of the field, so its + size may not be the same as the size of its type. This happens + with bitfields, of course (an `int' bitfield may be only 2 bits, + say), but it also happens with other fields. For example, the + C++ front-end creates zero-sized fields corresponding to empty + base classes, and depends on layout_type setting + DECL_FIELD_BITPOS correctly for the field. */ + if (integer_zerop (DECL_SIZE (decl)) + && DECL_NAME (decl) != NULL_TREE) abort (); /* Size is specified in number of bits. */ - DECL_SIZE (decl) = bitsize_int (spec_size); + spec_size = TREE_INT_CST_LOW (DECL_SIZE (decl)); if (spec_size % BITS_PER_UNIT == 0) DECL_SIZE_UNIT (decl) = size_int (spec_size / BITS_PER_UNIT); else @@ -313,8 +309,9 @@ layout_decl (decl, known_align) /* Force alignment required for the data type. But if the decl itself wants greater alignment, don't override that. Likewise, if the decl is packed, don't override it. */ - else if (DECL_ALIGN (decl) == 0 - || (! DECL_PACKED (decl) && TYPE_ALIGN (type) > DECL_ALIGN (decl))) + if (!(code == FIELD_DECL && DECL_BIT_FIELD (decl)) + && (DECL_ALIGN (decl) == 0 + || (! DECL_PACKED (decl) && TYPE_ALIGN (type) > DECL_ALIGN (decl)))) DECL_ALIGN (decl) = TYPE_ALIGN (type); /* See if we can use an ordinary integer mode for a bit-field. diff --git a/gcc/testsuite/g++.old-deja/g++.other/crash14.C b/gcc/testsuite/g++.old-deja/g++.other/crash14.C new file mode 100644 index 00000000000..85f093d7cc3 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/crash14.C @@ -0,0 +1,23 @@ +// Build don't link: +// Special g++ Options: -fnew-abi +// Origin: Mark Mitchell + +struct S +{ +}; + +struct T : public S +{ +}; + +struct U : public T +{ +}; + +void f (U); + +int main () +{ + U u; + f (u); +}