From: Ed Schonberg Date: Tue, 9 Oct 2018 15:05:54 +0000 (+0000) Subject: [Ada] Unnesting: fix handling of uplevel refs to unconstrained formals X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9e25affdbd810a3a40cc078d2a6415dd4b3baf7b;p=gcc.git [Ada] Unnesting: fix handling of uplevel refs to unconstrained formals 2018-10-09 Ed Schonberg gcc/ada/ * exp_unst.adb (Unnest_Subprogram): When an uplevel reference is to an unconstrained formal, the 'Access reference that is created to initialize the corresponding component of the activation record must be wrapped in an unchecked conversion to the generated type of the component. Otherwise, spurious suvtype conformance errors will be generated when the code is within an instantiation and the type of the formal is a formal type of the enclosing generic. Note that during unnesting there is no simple way to determine that the code appears within an instance because ther is no scope stack. From-SVN: r264972 --- diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 7f068b7e41e..f95316d554d 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,16 @@ +2018-10-09 Ed Schonberg + + * exp_unst.adb (Unnest_Subprogram): When an uplevel reference + is to an unconstrained formal, the 'Access reference that is + created to initialize the corresponding component of the + activation record must be wrapped in an unchecked conversion to + the generated type of the component. Otherwise, spurious suvtype + conformance errors will be generated when the code is within an + instantiation and the type of the formal is a formal type of the + enclosing generic. Note that during unnesting there is no simple + way to determine that the code appears within an instance + because ther is no scope stack. + 2018-10-09 Eric Botcazou * gcc-interface/decl.c (type_requires_init_of_formal): New diff --git a/gcc/ada/exp_unst.adb b/gcc/ada/exp_unst.adb index 0b63aa66fc5..8176fccfec2 100644 --- a/gcc/ada/exp_unst.adb +++ b/gcc/ada/exp_unst.adb @@ -1966,7 +1966,9 @@ package body Exp_Unst is Asn : Node_Id; Attr : Name_Id; + Comp : Entity_Id; Ins : Node_Id; + Rhs : Node_Id; begin -- For parameters, we insert the assignment @@ -2001,6 +2003,32 @@ package body Exp_Unst is Attr := Name_Address; end if; + Rhs := Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Ent, Loc), + Attribute_Name => Attr); + + -- If the entity is an unconstrained formal + -- we wrap the attribute reference in an + -- unchecked conversion to the type of the + -- activation record component, to prevent + -- spurious subtype conformance errors within + -- instances. + + if Is_Formal (Ent) + and then not Is_Constrained (Etype (Ent)) + then + -- Find target component and its type. + + Comp := First_Component (STJ.ARECnT); + while Chars (Comp) /= Chars (Ent) loop + Comp := Next_Component (Comp); + end loop; + + Rhs := Unchecked_Convert_To ( + Etype (Comp), Rhs); + end if; + Asn := Make_Assignment_Statement (Loc, Name => @@ -2012,12 +2040,7 @@ package body Exp_Unst is (Activation_Record_Component (Ent), Loc)), - - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Ent, Loc), - Attribute_Name => Attr)); + Expression => Rhs); -- If we have a loop parameter, we have -- to insert before the first statement