aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Baird <baird@adacore.com>2024-02-16 17:05:09 -0800
committerMarc Poulhiès <poulhies@adacore.com>2024-05-16 10:49:28 +0200
commita58b6be7f38e7a775f92b8aaa8d1c374a6e0c790 (patch)
tree0a59ab0b2c45d469559664c010ed457ed47ea55f
parentaaaa50ae8753fb7d65e810fa60fbd396f6d9e3d9 (diff)
downloadgcc-a58b6be7f38e7a775f92b8aaa8d1c374a6e0c790.zip
gcc-a58b6be7f38e7a775f92b8aaa8d1c374a6e0c790.tar.gz
gcc-a58b6be7f38e7a775f92b8aaa8d1c374a6e0c790.tar.bz2
ada: Follow up fixes for Put_Image/streaming regressions
A recent change to reduce duplication of compiler-generated Put_Image and streaming subprograms introduced some regressions. The fix for one of them was incomplete. gcc/ada/ * exp_attr.adb (Build_And_Insert_Type_Attr_Subp): Further tweaking of the point where a compiler-generated Put_Image or streaming subprogram is to be inserted in the tree. If one such subprogram calls another (as is often the case with, for example, Put_Image procedures for composite type and for a component type thereof), then we want to avoid use-before-definition problems that can result from inserting the caller ahead of the callee.
-rw-r--r--gcc/ada/exp_attr.adb38
1 files changed, 38 insertions, 0 deletions
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index e12e8b4..03bf4cf 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -1954,6 +1954,44 @@ package body Exp_Attr is
while Present (Ancestor) loop
if Is_List_Member (Ancestor) then
Insertion_Point := First (List_Containing (Ancestor));
+
+ -- A hazard to avoid here is use-before-definition
+ -- errors that can result when we have two of these
+ -- subprograms where one calls the other (e.g., given
+ -- Put_Image procedures for a composite type and
+ -- for a component type, the former will often call
+ -- the latter). At the time a subprogram is inserted,
+ -- we know that the one and only call to it is
+ -- somewhere in the subtree rooted at Ancestor.
+ -- So that placement constraint is easy to satisfy.
+ -- But if we construct another subprogram later and
+ -- if that second subprogram calls the first one,
+ -- then we need to be careful not to place the
+ -- second one ahead of the first one. That is the goal
+ -- of this loop. This may need to be revised if it turns
+ -- out that other stuff is being inserted on the list,
+ -- so that the loop terminates too early.
+
+ -- On the other hand, it seems like inserting things
+ -- earlier offers more opportunities for sharing.
+ -- If Ancestor occurs in the statement list of a
+ -- subprogram body (ignore the HSS node for now),
+ -- then perhaps we should look for an insertion site
+ -- in the decl list of the subprogram body and only
+ -- look in the statement list if the decl list is empty.
+ -- Similarly if Ancestor occors in the private decls list
+ -- for a package spec that has a non-empty visible
+ -- decls list. No examples where this would result in more
+ -- sharing and less duplication have been observed, so this
+ -- is just speculation.
+
+ while Insertion_Point /= Ancestor
+ and then Nkind (Insertion_Point) = N_Subprogram_Body
+ and then not Comes_From_Source (Insertion_Point)
+ loop
+ Next (Insertion_Point);
+ end loop;
+
pragma Assert (Present (Insertion_Point));
end if;
Ancestor := Parent (Ancestor);