mirror of git://gcc.gnu.org/git/gcc.git
decl.c (gnat_to_gnu_entity): Try to make a packable type for fields of union types as well.
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Subtype>: Try to make a packable type for fields of union types as well. <is_type>: Use RECORD_OR_UNION_TYPE_P predicate. (gnat_to_gnu_component_type): Try to make a packable type for fields of union types as well. (make_packable_type): Use RECORD_OR_UNION_TYPE_P predicate. (maybe_pad_type): Try to make a packable type for fields of union types as well. (gnat_to_gnu_field): Likewise. (is_variable_size): Use RECORD_OR_UNION_TYPE_P predicate. (set_rm_size): Likewise. (rm_size): Likewise. * gcc-interface/misc.c (gnat_type_max_size): Likewise. * gcc-interface/trans.c (add_decl_expr): Likewise. * gcc-interface/utils.c (finish_record_type): Likewise. * gcc-interface/utils2.c (build_simple_component_ref): Likewise. From-SVN: r180540
This commit is contained in:
parent
0025cb6381
commit
e1e5852c9f
|
@ -1,3 +1,23 @@
|
|||
|
||||
2011-10-26 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Subtype>: Try to
|
||||
make a packable type for fields of union types as well.
|
||||
<is_type>: Use RECORD_OR_UNION_TYPE_P predicate.
|
||||
(gnat_to_gnu_component_type): Try to make a packable type for fields
|
||||
of union types as well.
|
||||
(make_packable_type): Use RECORD_OR_UNION_TYPE_P predicate.
|
||||
(maybe_pad_type): Try to make a packable type for fields of union types
|
||||
as well.
|
||||
(gnat_to_gnu_field): Likewise.
|
||||
(is_variable_size): Use RECORD_OR_UNION_TYPE_P predicate.
|
||||
(set_rm_size): Likewise.
|
||||
(rm_size): Likewise.
|
||||
* gcc-interface/misc.c (gnat_type_max_size): Likewise.
|
||||
* gcc-interface/trans.c (add_decl_expr): Likewise.
|
||||
* gcc-interface/utils.c (finish_record_type): Likewise.
|
||||
* gcc-interface/utils2.c (build_simple_component_ref): Likewise.
|
||||
|
||||
2011-10-26 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gcc-interface/decl.c (gnat_to_gnu_field): Always check components
|
||||
|
|
|
@ -3302,7 +3302,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
== INTEGER_CST)
|
||||
{
|
||||
gnu_size = DECL_SIZE (gnu_old_field);
|
||||
if (TREE_CODE (gnu_field_type) == RECORD_TYPE
|
||||
if (RECORD_OR_UNION_TYPE_P (gnu_field_type)
|
||||
&& !TYPE_FAT_POINTER_P (gnu_field_type)
|
||||
&& host_integerp (TYPE_SIZE (gnu_field_type), 1))
|
||||
gnu_field_type
|
||||
|
@ -4645,13 +4645,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
tree size;
|
||||
|
||||
/* If a size was specified, take it into account. Otherwise
|
||||
use the RM size for records as the type size has already
|
||||
been adjusted to the alignment. */
|
||||
use the RM size for records or unions as the type size has
|
||||
already been adjusted to the alignment. */
|
||||
if (gnu_size)
|
||||
size = gnu_size;
|
||||
else if ((TREE_CODE (gnu_type) == RECORD_TYPE
|
||||
|| TREE_CODE (gnu_type) == UNION_TYPE
|
||||
|| TREE_CODE (gnu_type) == QUAL_UNION_TYPE)
|
||||
else if (RECORD_OR_UNION_TYPE_P (gnu_type)
|
||||
&& !TYPE_FAT_POINTER_P (gnu_type))
|
||||
size = rm_size (gnu_type);
|
||||
else
|
||||
|
@ -5300,7 +5298,7 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
|
|||
&& !Is_Bit_Packed_Array (gnat_array)
|
||||
&& !Has_Aliased_Components (gnat_array)
|
||||
&& !Strict_Alignment (gnat_type)
|
||||
&& TREE_CODE (gnu_type) == RECORD_TYPE
|
||||
&& RECORD_OR_UNION_TYPE_P (gnu_type)
|
||||
&& !TYPE_FAT_POINTER_P (gnu_type)
|
||||
&& host_integerp (TYPE_SIZE (gnu_type), 1))
|
||||
gnu_type = make_packable_type (gnu_type, false);
|
||||
|
@ -6357,9 +6355,7 @@ make_packable_type (tree type, bool in_record)
|
|||
tree new_field_type = TREE_TYPE (old_field);
|
||||
tree new_field, new_size;
|
||||
|
||||
if ((TREE_CODE (new_field_type) == RECORD_TYPE
|
||||
|| TREE_CODE (new_field_type) == UNION_TYPE
|
||||
|| TREE_CODE (new_field_type) == QUAL_UNION_TYPE)
|
||||
if (RECORD_OR_UNION_TYPE_P (new_field_type)
|
||||
&& !TYPE_FAT_POINTER_P (new_field_type)
|
||||
&& host_integerp (TYPE_SIZE (new_field_type), 1))
|
||||
new_field_type = make_packable_type (new_field_type, true);
|
||||
|
@ -6369,9 +6365,7 @@ make_packable_type (tree type, bool in_record)
|
|||
packable version of the record type, see finish_record_type. */
|
||||
if (!DECL_CHAIN (old_field)
|
||||
&& !TYPE_PACKED (type)
|
||||
&& (TREE_CODE (new_field_type) == RECORD_TYPE
|
||||
|| TREE_CODE (new_field_type) == UNION_TYPE
|
||||
|| TREE_CODE (new_field_type) == QUAL_UNION_TYPE)
|
||||
&& RECORD_OR_UNION_TYPE_P (new_field_type)
|
||||
&& !TYPE_FAT_POINTER_P (new_field_type)
|
||||
&& !TYPE_CONTAINS_TEMPLATE_P (new_field_type)
|
||||
&& TYPE_ADA_SIZE (new_field_type))
|
||||
|
@ -6533,7 +6527,7 @@ maybe_pad_type (tree type, tree size, unsigned int align,
|
|||
between them and it might be hard to overcome afterwards, including
|
||||
at the RTL level when the stand-alone object is accessed as a whole. */
|
||||
if (align != 0
|
||||
&& TREE_CODE (type) == RECORD_TYPE
|
||||
&& RECORD_OR_UNION_TYPE_P (type)
|
||||
&& TYPE_MODE (type) == BLKmode
|
||||
&& !TREE_ADDRESSABLE (type)
|
||||
&& TREE_CODE (orig_size) == INTEGER_CST
|
||||
|
@ -6833,7 +6827,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
|
|||
effects on the outer record type. A typical case is a field known to be
|
||||
byte-aligned and not to share a byte with another field. */
|
||||
if (!needs_strict_alignment
|
||||
&& TREE_CODE (gnu_field_type) == RECORD_TYPE
|
||||
&& RECORD_OR_UNION_TYPE_P (gnu_field_type)
|
||||
&& !TYPE_FAT_POINTER_P (gnu_field_type)
|
||||
&& host_integerp (TYPE_SIZE (gnu_field_type), 1)
|
||||
&& (packed == 1
|
||||
|
@ -7047,9 +7041,7 @@ is_variable_size (tree type)
|
|||
&& !TREE_CONSTANT (DECL_SIZE (TYPE_FIELDS (type))))
|
||||
return true;
|
||||
|
||||
if (TREE_CODE (type) != RECORD_TYPE
|
||||
&& TREE_CODE (type) != UNION_TYPE
|
||||
&& TREE_CODE (type) != QUAL_UNION_TYPE)
|
||||
if (!RECORD_OR_UNION_TYPE_P (type))
|
||||
return false;
|
||||
|
||||
for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
|
||||
|
@ -8090,9 +8082,7 @@ set_rm_size (Uint uint_size, tree gnu_type, Entity_Id gnat_entity)
|
|||
SET_TYPE_RM_SIZE (gnu_type, size);
|
||||
|
||||
/* ...or the Ada size for record and union types. */
|
||||
else if ((TREE_CODE (gnu_type) == RECORD_TYPE
|
||||
|| TREE_CODE (gnu_type) == UNION_TYPE
|
||||
|| TREE_CODE (gnu_type) == QUAL_UNION_TYPE)
|
||||
else if (RECORD_OR_UNION_TYPE_P (gnu_type)
|
||||
&& !TYPE_FAT_POINTER_P (gnu_type))
|
||||
SET_TYPE_ADA_SIZE (gnu_type, size);
|
||||
}
|
||||
|
@ -8944,10 +8934,8 @@ rm_size (tree gnu_type)
|
|||
rm_size (TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_type)))),
|
||||
DECL_SIZE (TYPE_FIELDS (gnu_type)));
|
||||
|
||||
/* For record types, we store the size explicitly. */
|
||||
if ((TREE_CODE (gnu_type) == RECORD_TYPE
|
||||
|| TREE_CODE (gnu_type) == UNION_TYPE
|
||||
|| TREE_CODE (gnu_type) == QUAL_UNION_TYPE)
|
||||
/* For record or union types, we store the size explicitly. */
|
||||
if (RECORD_OR_UNION_TYPE_P (gnu_type)
|
||||
&& !TYPE_FAT_POINTER_P (gnu_type)
|
||||
&& TYPE_ADA_SIZE (gnu_type))
|
||||
return TYPE_ADA_SIZE (gnu_type);
|
||||
|
|
|
@ -556,9 +556,8 @@ gnat_type_max_size (const_tree gnu_type)
|
|||
/* If we don't have a constant, see what we can get from TYPE_ADA_SIZE,
|
||||
which should stay untouched. */
|
||||
if (!host_integerp (max_unitsize, 1)
|
||||
&& (TREE_CODE (gnu_type) == RECORD_TYPE
|
||||
|| TREE_CODE (gnu_type) == UNION_TYPE
|
||||
|| TREE_CODE (gnu_type) == QUAL_UNION_TYPE)
|
||||
&& RECORD_OR_UNION_TYPE_P (gnu_type)
|
||||
&& !TYPE_FAT_POINTER_P (gnu_type)
|
||||
&& TYPE_ADA_SIZE (gnu_type))
|
||||
{
|
||||
tree max_adasize = max_size (TYPE_ADA_SIZE (gnu_type), true);
|
||||
|
|
|
@ -6754,10 +6754,8 @@ add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
|
|||
}
|
||||
/* In any case, we have to deal with our own TYPE_ADA_SIZE field. */
|
||||
else if (TREE_CODE (gnu_decl) == TYPE_DECL
|
||||
&& ((TREE_CODE (type) == RECORD_TYPE
|
||||
&& !TYPE_FAT_POINTER_P (type))
|
||||
|| TREE_CODE (type) == UNION_TYPE
|
||||
|| TREE_CODE (type) == QUAL_UNION_TYPE))
|
||||
&& RECORD_OR_UNION_TYPE_P (type)
|
||||
&& !TYPE_FAT_POINTER_P (type))
|
||||
MARK_VISITED (TYPE_ADA_SIZE (type));
|
||||
}
|
||||
else if (!DECL_EXTERNAL (gnu_decl))
|
||||
|
|
|
@ -726,9 +726,7 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
|
|||
tree this_size = DECL_SIZE (field);
|
||||
tree this_ada_size;
|
||||
|
||||
if ((TREE_CODE (type) == RECORD_TYPE
|
||||
|| TREE_CODE (type) == UNION_TYPE
|
||||
|| TREE_CODE (type) == QUAL_UNION_TYPE)
|
||||
if (RECORD_OR_UNION_TYPE_P (type)
|
||||
&& !TYPE_FAT_POINTER_P (type)
|
||||
&& !TYPE_CONTAINS_TEMPLATE_P (type)
|
||||
&& TYPE_ADA_SIZE (type))
|
||||
|
|
|
@ -1748,9 +1748,7 @@ build_simple_component_ref (tree record_variable, tree component,
|
|||
tree record_type = TYPE_MAIN_VARIANT (TREE_TYPE (record_variable));
|
||||
tree ref, inner_variable;
|
||||
|
||||
gcc_assert ((TREE_CODE (record_type) == RECORD_TYPE
|
||||
|| TREE_CODE (record_type) == UNION_TYPE
|
||||
|| TREE_CODE (record_type) == QUAL_UNION_TYPE)
|
||||
gcc_assert (RECORD_OR_UNION_TYPE_P (record_type)
|
||||
&& COMPLETE_TYPE_P (record_type)
|
||||
&& (component == NULL_TREE) != (field == NULL_TREE));
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2011-10-26 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gnat.dg/specs/unchecked_union.ads: Rename to...
|
||||
* gnat.dg/specs/unchecked_union1.ads: ...this.
|
||||
* gnat.dg/specs/unchecked_union2.ads: New test.
|
||||
|
||||
2011-10-26 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gnat.dg/specs/atomic1.ads: New test.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
with Interfaces; use Interfaces;
|
||||
|
||||
package Unchecked_Union is
|
||||
package Unchecked_Union1 is
|
||||
type Mode_Type is (Mode_B2);
|
||||
|
||||
type Value_Union (Mode : Mode_Type := Mode_B2) is record
|
||||
|
@ -17,4 +17,4 @@ package Unchecked_Union is
|
|||
end record;
|
||||
pragma Unchecked_Union (Value_Union);
|
||||
|
||||
end Unchecked_Union;
|
||||
end Unchecked_Union1;
|
|
@ -0,0 +1,30 @@
|
|||
-- { dg-do compile }
|
||||
|
||||
package Unchecked_Union2 is
|
||||
|
||||
type Small_Int is range 0 .. 2**19 - 1;
|
||||
|
||||
type R1 (B : Boolean := True) is record
|
||||
case B is
|
||||
when True => Data1 : Small_Int;
|
||||
when False => Data2 : Small_Int;
|
||||
end case;
|
||||
end record;
|
||||
|
||||
for R1 use record
|
||||
Data1 at 0 range 0 .. 18;
|
||||
Data2 at 0 range 0 .. 18;
|
||||
end record;
|
||||
for R1'Size use 24;
|
||||
|
||||
pragma Unchecked_Union (R1);
|
||||
|
||||
type R2 is record
|
||||
Data : R1;
|
||||
end record;
|
||||
|
||||
for R2 use record
|
||||
Data at 0 range 3 .. 26;
|
||||
end record;
|
||||
|
||||
end Unchecked_Union2;
|
Loading…
Reference in New Issue