[Ada] Redundant elaboration checks

Message ID 20101007092651.GA31335@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Oct. 7, 2010, 9:26 a.m.
In some rare cases, a call that appears within a local subprogram body may
generate elaboration checks twice. This patch ensures that only one elaboration
check is generated for any subprogram call. In addition to an efficiency issue,
this also prevents code insertions that are are left unanalyzed in the tree,
and subsequent back-end crashes.
No simple example available.

Tested on x86_64-pc-linux-gnu, committed on trunk

2010-10-07  Ed Schonberg  <schonberg@adacore.com>

	* sem_elab.adb (Check_A_Call): After inserting elaboration check, set
	proper flag to prevent a double elaboration check on the same call.
	* exp_util.adb (Insert_Actions): If the enclosing node is an
	Expression_With_Actions and it has been analyzed already, find
	insertion point further up in the tree.


Index: exp_util.adb
--- exp_util.adb	(revision 165080)
+++ exp_util.adb	(working copy)
@@ -2451,11 +2451,15 @@  package body Exp_Util is
             --  Case of appearing within an Expressions_With_Actions node. We
-            --  prepend the actions to the list of actions already there.
+            --  prepend the actions to the list of actions already there, if
+            --  the node has not been analyzed yet. Otherwise find insertion
+            --  location further up the tree.
             when N_Expression_With_Actions =>
-               Prepend_List (Ins_Actions, Actions (P));
-               return;
+               if not Analyzed (P) then
+                  Prepend_List (Ins_Actions, Actions (P));
+                  return;
+               end if;
             --  Case of appearing in the condition of a while expression or
             --  elsif. We insert the actions into the Condition_Actions field.
Index: sem_elab.adb
--- sem_elab.adb	(revision 165080)
+++ sem_elab.adb	(working copy)
@@ -939,6 +939,16 @@  package body Sem_Elab is
                  Make_Attribute_Reference (Loc,
                    Attribute_Name => Name_Elaborated,
                    Prefix => New_Occurrence_Of (Spec_Entity (E_Scope), Loc)));
+               --  Prevent duplicate elaboration checks on the same call,
+               --  which can happen if the body enclosing the call appears
+               --  itself in a call whose elaboration check is delayed.
+               if
+                 Nkind_In (N, N_Function_Call, N_Procedure_Call_Statement)
+               then
+                  Set_No_Elaboration_Check (N);
+               end if;
             end if;
          --  Case of static elaboration model