[multiple changes]
authorArnaud Charlet <charlet@gcc.gnu.org>
Mon, 2 May 2016 10:30:23 +0000 (12:30 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Mon, 2 May 2016 10:30:23 +0000 (12:30 +0200)
2016-05-02  Javier Miranda  <miranda@adacore.com>

* exp_util.ads, exp_util.adb (Force_Evaluation): Adding new formal.
(Remove_Side_Effects): Adding a new formal.
* exp_ch6.adb (Expand_Simple_Function_Return): Generating the
call to the _Postconditions procedure ensure that side-effects
are unconditionally removed.

2016-05-02  Ed Schonberg  <schonberg@adacore.com>

* sem_ch12.adb (Check_Formal_Package_Instance, Check_Mismatch):
Use original node to determine whether the declaration is for
a formal type declaration, to take into account that formwl
private types are rewritten as private extension declarations
to simplify semantic analysis.

From-SVN: r235742

gcc/ada/ChangeLog
gcc/ada/exp_ch6.adb
gcc/ada/exp_util.adb
gcc/ada/exp_util.ads
gcc/ada/sem_ch12.adb

index 866df4e..1ac7653 100644 (file)
@@ -1,3 +1,19 @@
+2016-05-02  Javier Miranda  <miranda@adacore.com>
+
+       * exp_util.ads, exp_util.adb (Force_Evaluation): Adding new formal.
+       (Remove_Side_Effects): Adding a new formal.
+       * exp_ch6.adb (Expand_Simple_Function_Return): Generating the
+       call to the _Postconditions procedure ensure that side-effects
+       are unconditionally removed.
+
+2016-05-02  Ed Schonberg  <schonberg@adacore.com>
+
+       * sem_ch12.adb (Check_Formal_Package_Instance, Check_Mismatch):
+       Use original node to determine whether the declaration is for
+       a formal type declaration, to take into account that formwl
+       private types are rewritten as private extension declarations
+       to simplify semantic analysis.
+
 2016-05-02  Gary Dismukes  <dismukes@adacore.com>
 
        * exp_ch9.adb, sem_ch6.adb, sem_ch6.ads: Minor reformatting and typo
index 8d0b963..4c89374 100644 (file)
@@ -6800,7 +6800,7 @@ package body Exp_Ch6 is
          --  once in the call to _Postconditions, and once in the actual return
          --  statement, but we can't have side effects happening twice.
 
-         Remove_Side_Effects (Exp);
+         Force_Evaluation (Exp, Mode => Strict);
 
          --  Generate call to _Postconditions
 
index b4efc93..06d3c32 100644 (file)
@@ -3118,7 +3118,8 @@ package body Exp_Util is
       Name_Req      : Boolean   := False;
       Related_Id    : Entity_Id := Empty;
       Is_Low_Bound  : Boolean   := False;
-      Is_High_Bound : Boolean   := False)
+      Is_High_Bound : Boolean   := False;
+      Mode          : Force_Evaluation_Mode := Relaxed)
    is
    begin
       Remove_Side_Effects
@@ -3128,7 +3129,10 @@ package body Exp_Util is
          Renaming_Req  => False,
          Related_Id    => Related_Id,
          Is_Low_Bound  => Is_Low_Bound,
-         Is_High_Bound => Is_High_Bound);
+         Is_High_Bound => Is_High_Bound,
+         Check_Side_Effects =>
+           Is_Static_Expression (Exp)
+             or else Mode = Relaxed);
    end Force_Evaluation;
 
    ---------------------------------
@@ -7545,13 +7549,14 @@ package body Exp_Util is
    -------------------------
 
    procedure Remove_Side_Effects
-     (Exp           : Node_Id;
-      Name_Req      : Boolean   := False;
-      Renaming_Req  : Boolean   := False;
-      Variable_Ref  : Boolean   := False;
-      Related_Id    : Entity_Id := Empty;
-      Is_Low_Bound  : Boolean   := False;
-      Is_High_Bound : Boolean   := False)
+     (Exp                : Node_Id;
+      Name_Req           : Boolean   := False;
+      Renaming_Req       : Boolean   := False;
+      Variable_Ref       : Boolean   := False;
+      Related_Id         : Entity_Id := Empty;
+      Is_Low_Bound       : Boolean   := False;
+      Is_High_Bound      : Boolean   := False;
+      Check_Side_Effects : Boolean   := True)
    is
       function Build_Temporary
         (Loc         : Source_Ptr;
@@ -7685,7 +7690,9 @@ package body Exp_Util is
 
       --  No action needed for side-effect free expressions
 
-      elsif Side_Effect_Free (Exp, Name_Req, Variable_Ref) then
+      elsif Check_Side_Effects
+        and then Side_Effect_Free (Exp, Name_Req, Variable_Ref)
+      then
          return;
       end if;
 
index 1bde973..9beb054 100644 (file)
@@ -526,19 +526,25 @@ package Exp_Util is
    --  Note: currently this function does not scan the private part, that seems
    --  like a potential bug ???
 
+   type Force_Evaluation_Mode is (Relaxed, Strict);
+
    procedure Force_Evaluation
      (Exp           : Node_Id;
       Name_Req      : Boolean   := False;
       Related_Id    : Entity_Id := Empty;
       Is_Low_Bound  : Boolean   := False;
-      Is_High_Bound : Boolean   := False);
+      Is_High_Bound : Boolean   := False;
+      Mode          : Force_Evaluation_Mode := Relaxed);
    --  Force the evaluation of the expression right away. Similar behavior
    --  to Remove_Side_Effects when Variable_Ref is set to TRUE. That is to
    --  say, it removes the side effects and captures the values of the
    --  variables. Remove_Side_Effects guarantees that multiple evaluations
    --  of the same expression won't generate multiple side effects, whereas
    --  Force_Evaluation further guarantees that all evaluations will yield
-   --  the same result.
+   --  the same result. If Mode is Relaxed then calls to this subprogram have
+   --  no effect if Exp is side-effects free; if Mode is Strict and Exp is not
+   --  a static expression then no side-effects check is performed on Exp and
+   --  temporaries are unconditionally generated.
    --
    --  Related_Id denotes the entity of the context where Expr appears. Flags
    --  Is_Low_Bound and Is_High_Bound specify whether the expression to check
@@ -861,13 +867,14 @@ package Exp_Util is
    --  associated with Var, and if found, remove and return that call node.
 
    procedure Remove_Side_Effects
-     (Exp           : Node_Id;
-      Name_Req      : Boolean   := False;
-      Renaming_Req  : Boolean   := False;
-      Variable_Ref  : Boolean   := False;
-      Related_Id    : Entity_Id := Empty;
-      Is_Low_Bound  : Boolean   := False;
-      Is_High_Bound : Boolean   := False);
+     (Exp                : Node_Id;
+      Name_Req           : Boolean   := False;
+      Renaming_Req       : Boolean   := False;
+      Variable_Ref       : Boolean   := False;
+      Related_Id         : Entity_Id := Empty;
+      Is_Low_Bound       : Boolean   := False;
+      Is_High_Bound      : Boolean   := False;
+      Check_Side_Effects : Boolean   := True);
    --  Given the node for a subexpression, this function replaces the node if
    --  necessary by an equivalent subexpression that is guaranteed to be side
    --  effect free. This is done by extracting any actions that could cause
@@ -880,7 +887,8 @@ package Exp_Util is
    --  expression. If Variable_Ref is set to True, a variable is considered as
    --  side effect (used in implementing Force_Evaluation). Note: after call to
    --  Remove_Side_Effects, it is safe to call New_Copy_Tree to obtain a copy
-   --  of the resulting expression.
+   --  of the resulting expression. If Check_Side_Effects is set to True then
+   --  no action is performed if Exp is known to be side-effect free.
    --
    --  Related_Id denotes the entity of the context where Expr appears. Flags
    --  Is_Low_Bound and Is_High_Bound specify whether the expression to check
index 04b7fb4..0d8446d 100644 (file)
@@ -5759,7 +5759,11 @@ package body Sem_Ch12 is
       --------------------
 
       procedure Check_Mismatch (B : Boolean) is
-         Kind : constant Node_Kind := Nkind (Parent (E2));
+         --  a Formal_Type_Declaration for a derived private type is rewritten
+         --  as a private extension decl. (see Analyze_Formal_Derived_Type),
+         --  which is why we examine the original node.
+
+         Kind : constant Node_Kind := Nkind (Original_Node (Parent (E2)));
 
       begin
          if Kind = N_Formal_Type_Declaration then
@@ -5923,7 +5927,10 @@ package body Sem_Ch12 is
          --  If the formal entity comes from a formal declaration, it was
          --  defaulted in the formal package, and no check is needed on it.
 
-         elsif Nkind (Parent (E2)) = N_Formal_Object_Declaration then
+         elsif
+           Nkind_In (Original_Node (Parent (E2)),
+             N_Formal_Object_Declaration, N_Formal_Type_Declaration)
+         then
             goto Next_E;
 
          --  Ditto for defaulted formal subprograms.