This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Ada] Fix wrong code for renaming of slice at library level
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 8 Sep 2007 12:30:55 +0200
- Subject: [Ada] Fix wrong code for renaming of slice at library level
This is a regression from the 4.2.x releases. The problem stems from a bad
interaction between renaming and the optimization done in Gigi for constants,
whereby the lvalue is replaced with the rvalue.
More specifically, renaming may involve taking the address of the object:
/* Case 4: Make this into a constant pointer to the object we
are to rename and attach the object to the pointer if it is
something we can stabilize.
[...]
gnu_expr
= build_unary_op (ADDR_EXPR, gnu_type, maybe_stable_expr);
although there is no such a thing in the tree handed down by the front-end.
Now the predicate invoked to decide whether to apply the optimization for
constants only looks at this tree and, consequently, doesn't see the need
for an lvalue. There is also a missing case for slices.
Tested on i586-suse-linux, applied to mainline.
2007-09-08 Eric Botcazou <ebotcazou@adacore.com>
* decl.c (gnat_to_gnu_entity) <Object>: Simplify the condition under
which a constant renaming is treated as a normal object declaration.
* trans.c (lvalue_required_p) <N_Slice>: New case, extracted from
the N_Indexed_Component case.
<N_Indexed_Component>: Fall through to above case.
<N_Object_Renaming_Declaration>: Return true for all composite types.
2007-09-08 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/renaming3.adb, renaming4.ads: New test.
--
Eric Botcazou
-- { dg-do run }
with Renaming4; use Renaming4;
procedure Renaming3 is
type A is array(1..16) of Integer;
Filler : A := (others => 0);
begin
if B(1) /= 1 then
raise Program_Error;
end if;
end;
package Renaming4 is
type Big_Array is array (Natural range <>) of Integer;
subtype Index is Natural range 1..4;
subtype My_Array is Big_Array(Index);
A : constant My_Array := (1, 2, 3, 4);
subtype Small is Index range 1..2;
subtype Small_Array is Big_Array(Small);
B : Small_Array renames A(Index);
end Renaming4;
Index: decl.c
===================================================================
--- decl.c (revision 128266)
+++ decl.c (working copy)
@@ -815,10 +815,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
/* Case 3: If this is a constant renaming and creating a
new object is allowed and cheap, treat it as a normal
object whose initial value is what is being renamed. */
- if (const_flag
- && Ekind (Etype (gnat_entity)) != E_Class_Wide_Type
- && TREE_CODE (gnu_type) != UNCONSTRAINED_ARRAY_TYPE
- && TYPE_MODE (gnu_type) != BLKmode)
+ if (const_flag && Is_Elementary_Type (Etype (gnat_entity)))
;
/* Case 4: Make this into a constant pointer to the object we
Index: trans.c
===================================================================
--- trans.c (revision 128261)
+++ trans.c (working copy)
@@ -384,20 +384,28 @@ lvalue_required_p (Node_Id gnat_node, tr
gnat_temp = Next (gnat_temp))
if (Nkind (gnat_temp) != N_Integer_Literal)
return 1;
- aliased |= Has_Aliased_Components (Etype (Prefix (gnat_node)));
- return lvalue_required_p (Parent (gnat_node), operand_type, aliased);
}
+ /* ... fall through ... */
+
+ case N_Slice:
+ aliased |= Has_Aliased_Components (Etype (Prefix (gnat_node)));
+ return lvalue_required_p (Parent (gnat_node), operand_type, aliased);
+
case N_Selected_Component:
aliased |= Is_Aliased (Entity (Selector_Name (gnat_node)));
return lvalue_required_p (Parent (gnat_node), operand_type, aliased);
case N_Object_Renaming_Declaration:
/* We need to make a real renaming only if the constant object is
- aliased; otherwise we can optimize and return the rvalue. We
- make an exception if the object is an identifier since in this
- case the rvalue can be propagated attached to the CONST_DECL. */
- return aliased || Nkind (Name (gnat_node)) == N_Identifier;
+ aliased or if we may use a renaming pointer; otherwise we can
+ optimize and return the rvalue. We make an exception if the object
+ is an identifier since in this case the rvalue can be propagated
+ attached to the CONST_DECL. */
+ return (aliased != 0
+ /* This should match the constant case of the renaming code. */
+ || Is_Composite_Type (Etype (Name (gnat_node)))
+ || Nkind (Name (gnat_node)) == N_Identifier);
default:
return 0;