From bee475e2e059ef30d5dae7eea0cb0e09c97a3f18 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 19 Sep 2019 08:14:38 +0000 Subject: [PATCH] [Ada] Fix copy operation with private discriminated record type This prevents the object code from reading too many bytes from the source for a copy operation involving a private discriminated record type with default discriminants and generated for the assignment of an aggregate to a variable or the initialization of a constant. The front-end already knows that it needs to convert the operation involving the aggregate into individual assignments if the type of the aggregate has mutable components, but it would not do so if this type is private, which does not change anything for code generation. Running these commands: gnatmake -q p -g -fsanitize=address p On the following sources: with Q; use Q; procedure P is type Rec is record A : T; end record; C : constant Rec := Rec'(A => Default_T); begin null; end; package Q is type T is private; Default_T : constant T; private A : constant := 170; B : constant := 8192; type A_Index is range 1 .. A; type B_Index is range 1 .. B; type A_Array is array (A_Index) of Boolean; type B_Array is array (B_Index) of Boolean; type Data_Type is (A_Type, B_Type); type T (Discriminant : Data_Type := A_Type) is record case Discriminant is when A_Type => Field_A : A_Array; when B_Type => Field_B : B_Array; end case; end record; Default_T : constant T := T'(Discriminant => A_Type, Field_A => (others => True)); end Q; Should execute silently. 2019-09-19 Eric Botcazou gcc/ada/ * exp_aggr.adb (Has_Mutable_Components): Look at the underlying type of components to find out whether they are mutable. From-SVN: r275954 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/exp_aggr.adb | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c10f7fffa79..ff666826090 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2019-09-19 Eric Botcazou + + * exp_aggr.adb (Has_Mutable_Components): Look at the underlying + type of components to find out whether they are mutable. + 2019-09-19 Eric Botcazou * sem_ch12.adb (Instantiate_Package_Body): Check that the body diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb index 63f9d1a512a..3d3dd1b8341 100644 --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -8162,13 +8162,15 @@ package body Exp_Aggr is function Has_Mutable_Components (Typ : Entity_Id) return Boolean is Comp : Entity_Id; + Ctyp : Entity_Id; begin Comp := First_Component (Typ); while Present (Comp) loop - if Is_Record_Type (Etype (Comp)) - and then Has_Discriminants (Etype (Comp)) - and then not Is_Constrained (Etype (Comp)) + Ctyp := Underlying_Type (Etype (Comp)); + if Is_Record_Type (Ctyp) + and then Has_Discriminants (Ctyp) + and then not Is_Constrained (Ctyp) then return True; end if; -- 2.30.2