Commit f88facfe by Eric Botcazou Committed by Eric Botcazou

utils.c (convert): In the padded case...

	* gcc-interface/utils.c (convert): In the padded case, do the final
	conversion as an unchecked conversion if the underlying types are
	array types with variable size.

From-SVN: r150965
parent 167f281e
2009-08-20 Eric Botcazou <ebotcazou@adacore.com> 2009-08-20 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/utils.c (convert): In the padded case, do the final
conversion as an unchecked conversion if the underlying types are
array types with variable size.
2009-08-20 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/ada-tree.h (SET_TYPE_RM_VALUE): Mark the expression * gcc-interface/ada-tree.h (SET_TYPE_RM_VALUE): Mark the expression
as visited. as visited.
* gcc-interface/misc (gnat_get_subrange_bounds): Always return the * gcc-interface/misc.c (gnat_get_subrange_bounds): Always return the
bounds. bounds.
* gcc-interface/trans.c (add_decl_expr): Do not mark gigi-specific * gcc-interface/trans.c (add_decl_expr): Do not mark gigi-specific
fields. fields.
......
...@@ -3810,13 +3810,13 @@ convert (tree type, tree expr) ...@@ -3810,13 +3810,13 @@ convert (tree type, tree expr)
== TYPE_NAME (TREE_TYPE (TYPE_FIELDS (etype))))) == TYPE_NAME (TREE_TYPE (TYPE_FIELDS (etype)))))
; ;
/* If the output type has padding, convert to the inner type and /* If the output type has padding, convert to the inner type and make a
make a constructor to build the record. */ constructor to build the record, unless a variable size is involved. */
else if (code == RECORD_TYPE && TYPE_IS_PADDING_P (type)) else if (code == RECORD_TYPE && TYPE_IS_PADDING_P (type))
{ {
/* If we previously converted from another type and our type is /* If we previously converted from another type and our type is
of variable size, remove the conversion to avoid the need for of variable size, remove the conversion to avoid the need for
variable-size temporaries. Likewise for a conversion between variable-sized temporaries. Likewise for a conversion between
original and packable version. */ original and packable version. */
if (TREE_CODE (expr) == VIEW_CONVERT_EXPR if (TREE_CODE (expr) == VIEW_CONVERT_EXPR
&& (!TREE_CONSTANT (TYPE_SIZE (type)) && (!TREE_CONSTANT (TYPE_SIZE (type))
...@@ -3827,7 +3827,7 @@ convert (tree type, tree expr) ...@@ -3827,7 +3827,7 @@ convert (tree type, tree expr)
/* If we are just removing the padding from expr, convert the original /* If we are just removing the padding from expr, convert the original
object if we have variable size in order to avoid the need for some object if we have variable size in order to avoid the need for some
variable-size temporaries. Likewise if the padding is a mere variant variable-sized temporaries. Likewise if the padding is a variant
of the other, so we avoid a pointless unpad/repad sequence. */ of the other, so we avoid a pointless unpad/repad sequence. */
if (TREE_CODE (expr) == COMPONENT_REF if (TREE_CODE (expr) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE
...@@ -3841,20 +3841,32 @@ convert (tree type, tree expr) ...@@ -3841,20 +3841,32 @@ convert (tree type, tree expr)
return convert (type, TREE_OPERAND (expr, 0)); return convert (type, TREE_OPERAND (expr, 0));
/* If the result type is a padded type with a self-referentially-sized /* If the result type is a padded type with a self-referentially-sized
field and the expression type is a record, do this as an field and the expression type is a record, do this as an unchecked
unchecked conversion. */ conversion. */
else if (TREE_CODE (etype) == RECORD_TYPE if (TREE_CODE (etype) == RECORD_TYPE
&& CONTAINS_PLACEHOLDER_P (DECL_SIZE (TYPE_FIELDS (type)))) && CONTAINS_PLACEHOLDER_P (DECL_SIZE (TYPE_FIELDS (type))))
return unchecked_convert (type, expr, false); return unchecked_convert (type, expr, false);
else /* If we are converting between array types with variable size, do the
return final conversion as an unchecked conversion, again to avoid the need
gnat_build_constructor (type, for some variable-sized temporaries. If valid, this conversion is
tree_cons (TYPE_FIELDS (type), very likely purely technical and without real effects. */
convert (TREE_TYPE if (TREE_CODE (etype) == ARRAY_TYPE
(TYPE_FIELDS (type)), && TREE_CODE (TREE_TYPE (TYPE_FIELDS (type))) == ARRAY_TYPE
expr), && !TREE_CONSTANT (TYPE_SIZE (etype))
NULL_TREE)); && !TREE_CONSTANT (TYPE_SIZE (type)))
return unchecked_convert (type,
convert (TREE_TYPE (TYPE_FIELDS (type)),
expr),
false);
return
gnat_build_constructor (type,
tree_cons (TYPE_FIELDS (type),
convert (TREE_TYPE
(TYPE_FIELDS (type)),
expr),
NULL_TREE));
} }
/* If the input type has padding, remove it and convert to the output type. /* If the input type has padding, remove it and convert to the output type.
......
2009-08-20 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/slice6.adb: New test.
* gnat.dg/slice6_pkg.ads: New helper.
2009-08-20 Michael Matz <matz@suse.de> 2009-08-20 Michael Matz <matz@suse.de>
PR fortran/41126 PR fortran/41126
......
-- { dg-do compile }
-- { dg-options "-gnatws" }
with Slice6_Pkg; use Slice6_Pkg;
procedure Slice6 is
procedure Send (V_LENGTH : SHORT_INTEGER) is
V : Integer;
V_BLOCK : T_BLOCK (1 .. 4096);
for V_BLOCK use at V'Address;
V_MSG : T_MSG ;
begin
V_MSG := (V_LENGTH, 1, V_BLOCK (1 .. V_LENGTH));
end;
begin
null;
end;
package Slice6_Pkg is
subtype LENGTH_RANGE is SHORT_INTEGER range 0 .. 8184;
type T_BLOCK is array (SHORT_INTEGER range <>) of SHORT_SHORT_INTEGER;
for T_BLOCK'alignment use 4;
type T_MSG (V_LENGTH : LENGTH_RANGE := 0) is
record
HEADER : Integer;
DATAS : T_BLOCK (1 .. V_LENGTH) := (others => 0);
end record;
for T_MSG'alignment use 4;
end Slice6_Pkg;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment