summaryrefslogtreecommitdiff
path: root/gcc/ada/exp_attr.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-04 14:56:27 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-04 14:56:27 +0000
commitd53a018a401689946f9010510d3de21179fe0004 (patch)
tree3765443613cb76c583fd3d45714d1ffc39b1086d /gcc/ada/exp_attr.adb
parent7cb910d31df6178b0e4a3b5662c64a58ae21008f (diff)
downloadgcc-d53a018a401689946f9010510d3de21179fe0004.tar.gz
2004-10-04 Ed Schonberg <schonberg@gnat.com>
* sem_util.adb (Explain_Limited_Type): Ignore internal components when searching for a limited component to flag. * exp_attr.adb (Freeze_Stream_Subprogram): Subsidiary procedure to expansion of Input, to account for the fact that the implicit call generated by the attribute reference must freeze the user-defined stream subprogram. This is only relevant to 'Input, because it can appear in an object declaration, prior to the body of the subprogram. * sem_ch13.adb (Rep_Item_Too_Late): Make the error non-serious, so that expansion can proceed and further errors uncovered. (Minor clean up): Fix cases of using | instead of \ for continuation messages. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88494 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/exp_attr.adb')
-rw-r--r--gcc/ada/exp_attr.adb68
1 files changed, 68 insertions, 0 deletions
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index f87d503db62..1ba1e03ca14 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -1737,6 +1737,44 @@ package body Exp_Attr is
-- the dispatching (class-wide type) case, where it is a reference
-- to the dummy object initialized to the right internal tag.
+ procedure Freeze_Stream_Subprogram (F : Entity_Id);
+ -- The expansion of the attribute reference may generate a call to
+ -- a user-defined stream subprogram that is frozen by the call. This
+ -- can lead to access-before-elaboration problem if the reference
+ -- appears in an object declaration and the subprogram body has not
+ -- been seen. The freezing of the subprogram requires special code
+ -- because it appears in an expanded context where expressions do
+ -- not freeze their constituents.
+
+ ------------------------------
+ -- Freeze_Stream_Subprogram --
+ ------------------------------
+
+ procedure Freeze_Stream_Subprogram (F : Entity_Id) is
+ Decl : constant Node_Id := Unit_Declaration_Node (F);
+ Bod : Node_Id;
+
+ begin
+ -- If this is user-defined subprogram, the corresponding
+ -- stream function appears as a renaming-as-body, and the
+ -- user subprogram must be retrieved by tree traversal.
+
+ if Present (Decl)
+ and then Nkind (Decl) = N_Subprogram_Declaration
+ and then Present (Corresponding_Body (Decl))
+ then
+ Bod := Corresponding_Body (Decl);
+
+ if Nkind (Unit_Declaration_Node (Bod)) =
+ N_Subprogram_Renaming_Declaration
+ then
+ Set_Is_Frozen (Entity (Name (Unit_Declaration_Node (Bod))));
+ end if;
+ end if;
+ end Freeze_Stream_Subprogram;
+
+ -- Start of processing for Input
+
begin
-- If no underlying type, we have an error that will be diagnosed
-- elsewhere, so here we just completely ignore the expansion.
@@ -1902,6 +1940,32 @@ package body Exp_Attr is
Build_Record_Or_Elementary_Input_Function
(Loc, Base_Type (U_Type), Decl, Fname);
Insert_Action (N, Decl);
+
+ if Nkind (Parent (N)) = N_Object_Declaration
+ and then Is_Record_Type (U_Type)
+ then
+ -- The stream function may contain calls to user-defined
+ -- Read procedures for individual components.
+
+ declare
+ Comp : Entity_Id;
+ Func : Entity_Id;
+
+ begin
+ Comp := First_Component (U_Type);
+ while Present (Comp) loop
+ Func :=
+ Find_Stream_Subprogram
+ (Etype (Comp), TSS_Stream_Read);
+
+ if Present (Func) then
+ Freeze_Stream_Subprogram (Func);
+ end if;
+
+ Next_Component (Comp);
+ end loop;
+ end;
+ end if;
end if;
end if;
@@ -1918,6 +1982,10 @@ package body Exp_Attr is
Set_Controlling_Argument (Call, Cntrl);
Rewrite (N, Unchecked_Convert_To (P_Type, Call));
Analyze_And_Resolve (N, P_Type);
+
+ if Nkind (Parent (N)) = N_Object_Declaration then
+ Freeze_Stream_Subprogram (Fname);
+ end if;
end Input;
-------------------