[Ada] Fix name clash in generated code

Arnaud Charlet charlet@adacore.com
Wed Feb 15 10:14:00 GMT 2006


Tested on i686-linux, committed on trunk

When the left-hand side of an array is packed it is not always possible
for the back-end to emit a block move, and the assignment must be expanded
into a loop of component assignments. If the right-hand side is a string,
we assign it first to a temporary, and the loop performs character by
character assignments. The temporary has an internally generated name to
prevent clashes with user-defined entities, but must also be unique over
the current scope to prevent spurious errors when several such assignments
occur in the same declarative region.
The following must compile quietly:
--
package P is
  pragma elaborate_body;
   type Rec is record
      C :   String (1..1);
      Bit : Boolean;
   end record;
   for Rec use record
      C   at 0 range 3..10;
      Bit at 0 range 31..31;
   end record;
   for Rec'Size use 32;
end P;
package body P is
  R1, R2 : Rec;
begin
  R1.C := "W";
  R2.C := "X";
end;

2006-02-13  Ed Schonberg  <schonberg@adacore.com>

	* exp_ch5.adb (Expand_Assign_Array): If the right-hand side is a
	string, and the context requires a loop for the assignment (e.g.
	because the left-hand side is packed), generate a unique name for the
	temporary that holds the string, to prevent spurious name clashes.

-------------- next part --------------
Index: exp_ch5.adb
===================================================================
--- exp_ch5.adb	(revision 110833)
+++ exp_ch5.adb	(working copy)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2005, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2006, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -506,7 +506,7 @@
       if Nkind (Rhs) = N_String_Literal then
          declare
             Temp : constant Entity_Id :=
-                     Make_Defining_Identifier (Loc, Name_T);
+                     Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
             Decl : Node_Id;
 
          begin
@@ -1631,18 +1631,6 @@
          Apply_Constraint_Check (Rhs, Etype (Lhs));
       end if;
 
-      --  If we are assigning an access type and the left side is an
-      --  entity, then make sure that Is_Known_Non_Null properly
-      --  reflects the state of the entity after the assignment
-
-      if Is_Access_Type (Typ)
-        and then Is_Entity_Name (Lhs)
-        and then Known_Non_Null (Rhs)
-        and then Safe_To_Capture_Value (N, Entity (Lhs))
-      then
-         Set_Is_Known_Non_Null (Entity (Lhs), Known_Non_Null (Rhs));
-      end if;
-
       --  Case of assignment to a bit packed array element
 
       if Nkind (Lhs) = N_Indexed_Component
@@ -2809,14 +2797,14 @@
 
       --  Nothing to do if we are returning by reference, or this is not
       --  a type that requires special processing (indicated by the fact
-      --  that it requires a cleanup scope for the secondary stack case)
+      --  that it requires a cleanup scope for the secondary stack case).
 
       if Is_Return_By_Reference_Type (T) then
          null;
 
       elsif not Requires_Transient_Scope (Return_Type) then
 
-         --  mutable records with no variable length components are not
+         --  Mutable records with no variable length components are not
          --  returned on the sec-stack so we need to make sure that the
          --  backend will only copy back the size of the actual value  and not
          --  the maximum size. We create an actual subtype for this purpose


More information about the Gcc-patches mailing list