This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Ada] Fix ICE with inaccurate representation clause
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 20 Apr 2009 10:21:34 +0200
- Subject: [Ada] Fix ICE with inaccurate representation clause
Gigi has a mechanism to ensure that objects (typically fields) that are not
addressable but nevertheless need to be passed by reference for "technical"
reasons are correctly passed: it creates a temporary and passes the address
of this temporary, copying it back afterwards if the parameter is In Out.
Special care must be taken with padding types, i.e. types built specifically
to meet a representation clause. They must be stripped if the nominal type
of the object is not padded, e.g. a field with an inaccurate representation
clause, but preserved if it is. For the attached testcase the compiler was
failing to strip a padded type for such a field, resulting in a ICE when it
is passed by reference as per the target ABI.
Tested on i586-suse-linux, applied on the mainline.
2009-04-20 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/trans.c (call_to_gnu): When creating the copy for a
non-addressable parameter passed by reference, do not convert the
actual if its type is already the nominal type, unless it is of
self-referential size.
2009-04-20 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/rep_clause3.adb: New test.
--
Eric Botcazou
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c (revision 146347)
+++ gcc-interface/trans.c (working copy)
@@ -2511,12 +2511,19 @@ call_to_gnu (Node_Id gnat_node, tree *gn
gnat_formal);
}
- /* Remove any unpadding from the object and reset the copy. */
- if (TREE_CODE (gnu_name) == COMPONENT_REF
- && ((TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_name, 0)))
- == RECORD_TYPE)
- && (TYPE_IS_PADDING_P
- (TREE_TYPE (TREE_OPERAND (gnu_name, 0))))))
+ /* If the actual type of the object is already the nominal type,
+ we have nothing to do, except if the size is self-referential
+ in which case we'll remove the unpadding below. */
+ if (TREE_TYPE (gnu_name) == gnu_name_type
+ && !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_name_type)))
+ ;
+
+ /* Otherwise remove unpadding from the object and reset the copy. */
+ else if (TREE_CODE (gnu_name) == COMPONENT_REF
+ && ((TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_name, 0)))
+ == RECORD_TYPE)
+ && (TYPE_IS_PADDING_P
+ (TREE_TYPE (TREE_OPERAND (gnu_name, 0))))))
gnu_name = gnu_copy = TREE_OPERAND (gnu_name, 0);
/* Otherwise convert to the nominal type of the object if it's
@@ -2529,7 +2536,7 @@ call_to_gnu (Node_Id gnat_node, tree *gn
else if (TREE_CODE (gnu_name_type) == RECORD_TYPE
&& (TYPE_JUSTIFIED_MODULAR_P (gnu_name_type)
|| smaller_packable_type_p (TREE_TYPE (gnu_name),
- gnu_name_type)))
+ gnu_name_type)))
gnu_name = convert (gnu_name_type, gnu_name);
/* Make a SAVE_EXPR to both properly account for potential side
-- { dg-do compile }
-- { dg-options "-gnatws" }
procedure Rep_Clause3 is
subtype U_16 is integer range 0..2**16-1;
type TYPE1 is range 0 .. 135;
for TYPE1'size use 14;
type TYPE2 is range 0 .. 262_143;
for TYPE2'size use 18;
subtype TYPE3 is integer range 1 .. 21*6;
type ARR is array (TYPE3 range <>) of boolean;
pragma Pack(ARR);
subtype SUB_ARR is ARR(1 .. 5*6);
OBJ : SUB_ARR;
type R is
record
N : TYPE1;
L : TYPE2;
I : SUB_ARR;
CRC : U_16;
end record;
for R use
record at mod 4;
N at 0 range 0 .. 13;
L at 0 range 14 .. 31;
I at 4 range 2 .. 37;
CRC at 8 range 16 .. 31;
end record;
for R'size use 12*8;
type SUB_R is array (1..4) of R;
T : SUB_R;
begin
if OBJ = T(1).I then
raise Program_Error;
end if;
end;