diff mbox

[Ada] Insertion of generated constructs in N_Expression_With_Actions nodes

Message ID 20130129142720.GA12770@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Jan. 29, 2013, 2:27 p.m. UTC
This patch corrects the mechanism that inserts various generated constructs in
the tree, in particular the interaction with expression_with_actions nodes. No
test case applicable as this latent bug was found during code reading.

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

2013-01-29  Hristian Kirtchev  <kirtchev@adacore.com>

	* exp_util.adb (Insert_Actions): When new
	actions come from the expression of the expression with actions,
	then they must be added to the list of existing actions.
diff mbox

Patch

Index: exp_util.adb
===================================================================
--- exp_util.adb	(revision 195533)
+++ exp_util.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2012, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2013, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -3141,25 +3141,27 @@ 
 
       --  N_Raise_xxx_Error is an annoying special case, it is a statement if
       --  it has type Standard_Void_Type, and a subexpression otherwise.
-      --  otherwise. Procedure attribute references are also statements.
+      --  otherwise. Procedure calls, and similarly procedure attribute
+      --  references, are also statements.
 
       if Nkind (Assoc_Node) in N_Subexpr
-        and then (Nkind (Assoc_Node) in N_Raise_xxx_Error
+        and then (Nkind (Assoc_Node) not in N_Raise_xxx_Error
                    or else Etype (Assoc_Node) /= Standard_Void_Type)
+        and then Nkind (Assoc_Node) /= N_Procedure_Call_Statement
         and then (Nkind (Assoc_Node) /= N_Attribute_Reference
                    or else
                      not Is_Procedure_Attribute_Name
                            (Attribute_Name (Assoc_Node)))
       then
-         P := Assoc_Node;             -- ??? does not agree with above!
-         N := Parent (Assoc_Node);
+         N := Assoc_Node;
+         P := Parent (Assoc_Node);
 
       --  Non-subexpression case. Note that N is initially Empty in this case
       --  (N is only guaranteed Non-Empty in the subexpr case).
 
       else
+         N := Empty;
          P := Assoc_Node;
-         N := Empty;
       end if;
 
       --  Capture root of the transient scope
@@ -3171,6 +3173,13 @@ 
       loop
          pragma Assert (Present (P));
 
+         --  Make sure that inserted actions stay in the transient scope
+
+         if Present (Wrapped_Node) and then N = Wrapped_Node then
+            Store_Before_Actions_In_Scope (Ins_Actions);
+            return;
+         end if;
+
          case Nkind (P) is
 
             --  Case of right operand of AND THEN or OR ELSE. Put the actions
@@ -3282,14 +3291,17 @@ 
 
                return;
 
-            --  Case of appearing within an Expressions_With_Actions node. We
-            --  append 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.
+            --  Case of appearing within an Expressions_With_Actions node. When
+            --  the new actions come from the expression of the expression with
+            --  actions, they must be added to the existing actions. The other
+            --  alternative is when the new actions are related to one of the
+            --  existing actions of the expression with actions. In that case
+            --  they must be inserted further up the tree.
 
             when N_Expression_With_Actions =>
-               if not Analyzed (P) then
-                  Append_List (Ins_Actions, Actions (P));
+               if N = Expression (P) then
+                  Insert_List_After_And_Analyze
+                    (Last (Actions (P)), Ins_Actions);
                   return;
                end if;
 
@@ -3697,13 +3709,6 @@ 
 
          end case;
 
-         --  Make sure that inserted actions stay in the transient scope
-
-         if P = Wrapped_Node then
-            Store_Before_Actions_In_Scope (Ins_Actions);
-            return;
-         end if;
-
          --  If we fall through above tests, keep climbing tree
 
          N := P;