decl.c (maybe_pad_type): Use TYPE_SIZE_UNIT of the input type for TYPE_SIZE_UNIT of result type if...
* decl.c (maybe_pad_type): Use TYPE_SIZE_UNIT of the input type for TYPE_SIZE_UNIT of result type if SIZE is not specified. (make_aligning_type): Pass -1 as ADDRESSABLE to prevent the creation of a bitfield, which we know is useless and causes trouble because of alignment implications. * utils.c (create_var_decl): Set DECL_COMMON again on targets without BSS sections. (process_attributes): Clear DECL_COMMON again when a section attribute is present. (finish_record_type): Independently track if RECORD_TYPE has SIZE and/or SIZE_UNIT already set and use to compute final SIZE and SIZE_UNIT. (create_field_decl): Special case ADDRESSABLE negative to mean "no bitfield creation", to be used by make_aligning_type. Don't restrict bitfield creation to !ADDRESSABLE any more, as some BLKmode fields claimed addressable still have to be bitfields. Use value_factor_p instead of a raw binop construction to check for the position's alignment. From-SVN: r91879
This commit is contained in:
parent
a4c1cd8065
commit
0da07eae29
@ -4618,7 +4618,6 @@ make_aligning_type (tree type, int align, tree size)
|
||||
/* The bit position is obtained by "and"ing the alignment minus 1
|
||||
with the two's complement of the address and multiplying
|
||||
by the number of bits per unit. Do all this in sizetype. */
|
||||
|
||||
pos = size_binop (MULT_EXPR,
|
||||
convert (bitsizetype,
|
||||
size_binop (BIT_AND_EXPR,
|
||||
@ -4628,9 +4627,13 @@ make_aligning_type (tree type, int align, tree size)
|
||||
- 1))),
|
||||
bitsize_unit_node);
|
||||
|
||||
field = create_field_decl (get_identifier ("F"), type, record_type,
|
||||
1, size, pos, 1);
|
||||
DECL_BIT_FIELD (field) = 0;
|
||||
/* Create the field, with -1 as the 'addressable' indication to avoid the
|
||||
creation of a bitfield. We don't need one, it would have damaging
|
||||
consequences on the alignment computation, and create_field_decl would
|
||||
make one without this special argument, for instance because of the
|
||||
complex position expression. */
|
||||
field = create_field_decl (get_identifier ("F"), type, record_type, 1, size,
|
||||
pos, -1);
|
||||
|
||||
finish_record_type (record_type, field, true, false);
|
||||
TYPE_ALIGN (record_type) = BIGGEST_ALIGNMENT;
|
||||
@ -4822,9 +4825,10 @@ maybe_pad_type (tree type, tree size, unsigned int align,
|
||||
DECL_INTERNAL_P (field) = 1;
|
||||
TYPE_SIZE (record) = size ? size : orig_size;
|
||||
TYPE_SIZE_UNIT (record)
|
||||
= convert (sizetype,
|
||||
size_binop (CEIL_DIV_EXPR, TYPE_SIZE (record),
|
||||
bitsize_unit_node));
|
||||
= (size ? convert (sizetype,
|
||||
size_binop (CEIL_DIV_EXPR, size, bitsize_unit_node))
|
||||
: TYPE_SIZE_UNIT (type));
|
||||
|
||||
TYPE_ALIGN (record) = align;
|
||||
TYPE_IS_PADDING_P (record) = 1;
|
||||
TYPE_VOLATILE (record)
|
||||
|
@ -740,6 +740,8 @@ finish_record_type (tree record_type, tree fieldlist, bool has_rep,
|
||||
tree ada_size = bitsize_zero_node;
|
||||
tree size = bitsize_zero_node;
|
||||
bool var_size = false;
|
||||
bool had_size = TYPE_SIZE (record_type) != 0;
|
||||
bool had_size_unit = TYPE_SIZE_UNIT (record_type) != 0;
|
||||
tree field;
|
||||
|
||||
TYPE_FIELDS (record_type) = fieldlist;
|
||||
@ -757,11 +759,12 @@ finish_record_type (tree record_type, tree fieldlist, bool has_rep,
|
||||
{
|
||||
TYPE_ALIGN (record_type) = MAX (BITS_PER_UNIT, TYPE_ALIGN (record_type));
|
||||
TYPE_MODE (record_type) = BLKmode;
|
||||
if (!TYPE_SIZE (record_type))
|
||||
{
|
||||
TYPE_SIZE (record_type) = bitsize_zero_node;
|
||||
|
||||
if (!had_size_unit)
|
||||
TYPE_SIZE_UNIT (record_type) = size_zero_node;
|
||||
}
|
||||
|
||||
if (!had_size)
|
||||
TYPE_SIZE (record_type) = bitsize_zero_node;
|
||||
/* For all-repped records with a size specified, lay the QUAL_UNION_TYPE
|
||||
out just like a UNION_TYPE, since the size will be fixed. */
|
||||
else if (code == QUAL_UNION_TYPE)
|
||||
@ -881,18 +884,14 @@ finish_record_type (tree record_type, tree fieldlist, bool has_rep,
|
||||
|
||||
if (has_rep)
|
||||
{
|
||||
if (!(TREE_CODE (record_type) == RECORD_TYPE
|
||||
&& TYPE_IS_PADDING_P (record_type)
|
||||
&& CONTAINS_PLACEHOLDER_P (size)))
|
||||
{
|
||||
tree size_unit
|
||||
= convert (sizetype, size_binop (CEIL_DIV_EXPR, size,
|
||||
bitsize_unit_node));
|
||||
TYPE_SIZE (record_type) = round_up (size, TYPE_ALIGN (record_type));
|
||||
TYPE_SIZE_UNIT (record_type)
|
||||
= round_up (size_unit,
|
||||
TYPE_ALIGN (record_type) / BITS_PER_UNIT);
|
||||
}
|
||||
tree size_unit
|
||||
= (had_size_unit ? TYPE_SIZE_UNIT (record_type)
|
||||
: convert (sizetype, size_binop (CEIL_DIV_EXPR, size,
|
||||
bitsize_unit_node)));
|
||||
|
||||
TYPE_SIZE (record_type) = round_up (size, TYPE_ALIGN (record_type));
|
||||
TYPE_SIZE_UNIT (record_type)
|
||||
= round_up (size_unit, TYPE_ALIGN (record_type) / BITS_PER_UNIT);
|
||||
|
||||
compute_record_mode (record_type);
|
||||
}
|
||||
@ -1339,6 +1338,13 @@ create_var_decl (tree var_name, tree asm_name, tree type, tree var_init,
|
||||
|| (type_annotate_only && var_init && !TREE_CONSTANT (var_init)))
|
||||
var_init = NULL_TREE;
|
||||
|
||||
/* Ada doesn't feature Fortran-like COMMON variables so we shouldn't
|
||||
try to fiddle with DECL_COMMON. However, on platforms that don't
|
||||
support global BSS sections, uninitialized global variables would
|
||||
go in DATA instead, thus increasing the size of the executable. */
|
||||
#if !defined(ASM_OUTPUT_BSS) && !defined(ASM_OUTPUT_ALIGNED_BSS)
|
||||
DECL_COMMON (var_decl) = !flag_no_common;
|
||||
#endif
|
||||
DECL_INITIAL (var_decl) = var_init;
|
||||
TREE_READONLY (var_decl) = const_flag;
|
||||
DECL_EXTERNAL (var_decl) = extern_flag;
|
||||
@ -1376,7 +1382,8 @@ create_var_decl (tree var_name, tree asm_name, tree type, tree var_init,
|
||||
this field is in a record type with a "pragma pack". If SIZE is nonzero
|
||||
it is the specified size for this field. If POS is nonzero, it is the bit
|
||||
position. If ADDRESSABLE is nonzero, it means we are allowed to take
|
||||
the address of this field for aliasing purposes. */
|
||||
the address of this field for aliasing purposes. If it is negative, we
|
||||
should not make a bitfield, which is used by make_aligning_type. */
|
||||
|
||||
tree
|
||||
create_field_decl (tree field_name, tree field_type, tree record_type,
|
||||
@ -1410,13 +1417,13 @@ create_field_decl (tree field_name, tree field_type, tree record_type,
|
||||
size = round_up (size, BITS_PER_UNIT);
|
||||
}
|
||||
|
||||
/* Make a bitfield if a size is specified for two reasons: first if the size
|
||||
differs from the natural size. Second, if the alignment is insufficient.
|
||||
There are a number of ways the latter can be true.
|
||||
/* If we may, according to ADDRESSABLE, make a bitfield if a size is
|
||||
specified for two reasons: first if the size differs from the natural
|
||||
size. Second, if the alignment is insufficient. There are a number of
|
||||
ways the latter can be true.
|
||||
|
||||
We never make a bitfield if the type of the field has a nonconstant size,
|
||||
or if it is claimed to be addressable, because no such entity requiring
|
||||
bitfield operations should reach here.
|
||||
because no such entity requiring bitfield operations should reach here.
|
||||
|
||||
We do *preventively* make a bitfield when there might be the need for it
|
||||
but we don't have all the necessary information to decide, as is the case
|
||||
@ -1424,15 +1431,13 @@ create_field_decl (tree field_name, tree field_type, tree record_type,
|
||||
|
||||
We also don't look at STRICT_ALIGNMENT here, and rely on later processing
|
||||
in layout_decl or finish_record_type to clear the bit_field indication if
|
||||
it is in fact not needed. */
|
||||
if (size && TREE_CODE (size) == INTEGER_CST
|
||||
it is in fact not needed. */
|
||||
if (addressable >= 0
|
||||
&& size
|
||||
&& TREE_CODE (size) == INTEGER_CST
|
||||
&& TREE_CODE (TYPE_SIZE (field_type)) == INTEGER_CST
|
||||
&& !addressable
|
||||
&& (!operand_equal_p (TYPE_SIZE (field_type), size, 0)
|
||||
|| (pos
|
||||
&& !value_zerop (size_binop (TRUNC_MOD_EXPR, pos,
|
||||
bitsize_int (TYPE_ALIGN
|
||||
(field_type)))))
|
||||
|| (pos && !value_factor_p (pos, TYPE_ALIGN (field_type)))
|
||||
|| packed
|
||||
|| (TYPE_ALIGN (record_type) != 0
|
||||
&& TYPE_ALIGN (record_type) < TYPE_ALIGN (field_type))))
|
||||
@ -1588,6 +1593,7 @@ process_attributes (tree decl, struct attrib *attr_list)
|
||||
DECL_SECTION_NAME (decl)
|
||||
= build_string (IDENTIFIER_LENGTH (attr_list->name),
|
||||
IDENTIFIER_POINTER (attr_list->name));
|
||||
DECL_COMMON (decl) = 0;
|
||||
}
|
||||
else
|
||||
post_error ("?section attributes are not supported for this target",
|
||||
|
Loading…
Reference in New Issue
Block a user