This changes the logic of Is_Non_Local_Array to return true for anything that
is not a component or a slice of a local entity, for example a dereference, so
as to generate a call to memmove instead of memcpy in more cases, e.g.:
package P is
type String_Access is access all String;
type Rec1 is record
A : String_Access;
end record;
procedure Proc (R : Rec1; S : String);
end P;
package body P is
procedure Proc (R : Rec1; S : String) is
begin
R.A (1 .. S'Length) := S;
end;
end P;
This will also fix PR ada/64057.
Tested on x86_64-pc-linux-gnu, committed on trunk
2016-10-12 Eric Botcazou <[email protected]>
PR ada/64057.
* exp_ch5.adb (Is_Non_Local_Array): Return true for every array
that is not a component or slice of an entity in the current
scope.
Index: exp_ch5.adb
===================================================================
--- exp_ch5.adb (revision 241024)
+++ exp_ch5.adb (working copy)
@@ -278,9 +278,9 @@
function Is_Non_Local_Array (Exp : Node_Id) return Boolean;
-- Determine if Exp is a reference to an array variable which is other
- -- than an object defined in the current scope, or a slice of such
- -- an object. Such objects can be aliased to parameters (unlike local
- -- array references).
+ -- than an object defined in the current scope, or a component or a
+ -- slice of such an object. Such objects can be aliased to parameters
+ -- (unlike local array references).
-----------------------
-- Apply_Dereference --
@@ -327,10 +327,14 @@
function Is_Non_Local_Array (Exp : Node_Id) return Boolean is
begin
- return (Is_Entity_Name (Exp)
- and then Scope (Entity (Exp)) /= Current_Scope)
- or else (Nkind (Exp) = N_Slice
- and then Is_Non_Local_Array (Prefix (Exp)));
+ case Nkind (Exp) is
+ when N_Indexed_Component | N_Selected_Component | N_Slice =>
+ return Is_Non_Local_Array (Prefix (Exp));
+ when others =>
+ return
+ not (Is_Entity_Name (Exp) and then
+ Scope (Entity (Exp)) = Current_Scope);
+ end case;
end Is_Non_Local_Array;
-- Determine if Lhs, Rhs are formal arrays or nonlocal arrays