[multiple changes]
authorArnaud Charlet <charlet@gcc.gnu.org>
Wed, 19 Feb 2014 10:25:53 +0000 (11:25 +0100)
committerArnaud Charlet <charlet@gcc.gnu.org>
Wed, 19 Feb 2014 10:25:53 +0000 (11:25 +0100)
2014-02-19  Robert Dewar  <dewar@adacore.com>

* exp_attr.adb (Expand_Min_Max_Attribute): New procedure
(Expand_N_Attribute_Reference): Use this procedure for Min and Max.
* exp_ch4.adb (Expand_N_Expression_With_Actions): Remove object
declarations from list of actions.
* output.ads, output.adb (Delete_Last_Char): New procedure.
* sinfo.ads: Document handling of Mod and expression with actions
in Modify_Tree_For_C mode.

2014-02-19  Ed Schonberg  <schonberg@adacore.com>

* par-ch9.adb (P_Task): Add a null statement to produce a
well-formed task body when due to a previous syntax error the
statement list is empty.

2014-02-19  Hristian Kirtchev  <kirtchev@adacore.com>

* sem_prag.adb (Check_Dependency_Clause): Account
for the case where a state with a non-null refinement matches a
null output list. Comment reformatting.
(Inputs_Match): Copy a solitary input to avoid an assertion failure
when trying to match the same input in multiple clauses.

2014-02-19  Gary Dismukes  <dismukes@adacore.com>

* sem_attr.adb: Minor typo fix.

From-SVN: r207880

gcc/ada/ChangeLog
gcc/ada/exp_attr.adb
gcc/ada/exp_ch4.adb
gcc/ada/output.adb
gcc/ada/output.ads
gcc/ada/par-ch9.adb
gcc/ada/sem_attr.adb
gcc/ada/sem_prag.adb
gcc/ada/sinfo.ads

index a7937443ddc736bc796d76eb1c7410b14c606b7f..d456c84c91354fab49f388568e85c24dd6e16dee 100644 (file)
@@ -1,3 +1,31 @@
+2014-02-19  Robert Dewar  <dewar@adacore.com>
+
+       * exp_attr.adb (Expand_Min_Max_Attribute): New procedure
+       (Expand_N_Attribute_Reference): Use this procedure for Min and Max.
+       * exp_ch4.adb (Expand_N_Expression_With_Actions): Remove object
+       declarations from list of actions.
+       * output.ads, output.adb (Delete_Last_Char): New procedure.
+       * sinfo.ads: Document handling of Mod and expression with actions
+       in Modify_Tree_For_C mode.
+
+2014-02-19  Ed Schonberg  <schonberg@adacore.com>
+
+       * par-ch9.adb (P_Task): Add a null statement to produce a
+       well-formed task body when due to a previous syntax error the
+       statement list is empty.
+
+2014-02-19  Hristian Kirtchev  <kirtchev@adacore.com>
+
+       * sem_prag.adb (Check_Dependency_Clause): Account
+       for the case where a state with a non-null refinement matches a
+       null output list. Comment reformatting.
+       (Inputs_Match): Copy a solitary input to avoid an assertion failure
+       when trying to match the same input in multiple clauses.
+
+2014-02-19  Gary Dismukes  <dismukes@adacore.com>
+
+       * sem_attr.adb: Minor typo fix.
+
 2014-02-18  Robert Dewar  <dewar@adacore.com>
 
        * cstand.adb (Build_Signed_Integer_Type): Minor change of formal
index 7a55d8b6c671f10adab1b55ec07640a5cc4aadcf..503a1ae3a21b35fdaafcf2d95b1d966be792e534 100644 (file)
@@ -140,6 +140,10 @@ package body Exp_Attr is
    --  Handle the expansion of attribute 'Loop_Entry. As a result, the related
    --  loop may be converted into a conditional block. See body for details.
 
+   procedure Expand_Min_Max_Attribute (N : Node_Id);
+   --  Handle the expansion of attributes 'Max and 'Min, including expanding
+   --  then out if we are in Modify_Tree_For_C mode.
+
    procedure Expand_Pred_Succ_Attribute (N : Node_Id);
    --  Handles expansion of Pred or Succ attributes for case of non-real
    --  operand with overflow checking required.
@@ -1035,6 +1039,116 @@ package body Exp_Attr is
       end if;
    end Expand_Loop_Entry_Attribute;
 
+   ------------------------------
+   -- Expand_Min_Max_Attribute --
+   ------------------------------
+
+   procedure Expand_Min_Max_Attribute (N : Node_Id) is
+   begin
+      --  Min and Max are handled by the back end (except that static cases
+      --  have already been evaluated during semantic processing, although the
+      --  back end should not count on this). The one bit of special processing
+      --  required in the normal case is that these two attributes typically
+      --  generate conditionals in the code, so check the relevant restriction.
+
+      Check_Restriction (No_Implicit_Conditionals, N);
+
+      --  In Modify_Tree_For_C mode, we rewrite as an if expression
+
+      if Modify_Tree_For_C then
+         declare
+            Loc   : constant Source_Ptr := Sloc (N);
+            Typ   : constant Entity_Id  := Etype (N);
+            Expr  : constant Node_Id    := First (Expressions (N));
+            Left  : constant Node_Id    := Relocate_Node (Expr);
+            Right : constant Node_Id    := Relocate_Node (Next (Expr));
+            Ltyp  : constant Entity_Id  := Etype (Left);
+            Rtyp  : constant Entity_Id  := Etype (Right);
+
+            function Make_Compare (Left, Right : Node_Id) return Node_Id;
+            --  Returns Left >= Right for Max, Left <= Right for Min
+
+            ------------------
+            -- Make_Compare --
+            ------------------
+
+            function Make_Compare (Left, Right : Node_Id) return Node_Id is
+            begin
+               if Attribute_Name (N) = Name_Max then
+                  return
+                    Make_Op_Ge (Loc,
+                      Left_Opnd  => Left,
+                      Right_Opnd => Right);
+               else
+                  return
+                    Make_Op_Le (Loc,
+                      Left_Opnd  => Left,
+                      Right_Opnd => Right);
+               end if;
+            end Make_Compare;
+
+         --  Start of processing for Min_Max
+
+         begin
+            --  If both Left and Right are simple entity names, then we can
+            --  just use Duplicate_Expr to duplicate the references and return
+
+            --    (if Left >=|<= Right then Left else Right)
+
+            if Is_Entity_Name (Left) and then Is_Entity_Name (Right) then
+               Rewrite (N,
+                 Make_If_Expression (Loc,
+                   Expressions => New_List (
+                     Make_Compare (Left, Right),
+                     Duplicate_Subexpr_No_Checks (Left),
+                     Duplicate_Subexpr_No_Checks (Right))));
+
+            --  Otherwise we wrap things in an expression with actions. You
+            --  might think we could just use the approach above, but there
+            --  are problems, in particular with escaped discriminants. In
+            --  this case we generate:
+
+            --    do
+            --      T1 : constant typ := Left;
+            --      T2 : constant typ := Right;
+            --    in
+            --      (if T1 >=|<= T2 then T1 else T2)
+            --    end;
+
+            else
+               declare
+                  T1 : constant Entity_Id := Make_Temporary (Loc, 'T', Left);
+                  T2 : constant Entity_Id := Make_Temporary (Loc, 'T', Left);
+
+               begin
+                  Rewrite (N,
+                    Make_Expression_With_Actions (Loc,
+                      Actions => New_List (
+                        Make_Object_Declaration (Loc,
+                          Defining_Identifier => T1,
+                          Object_Definition   => New_Occurrence_Of (Ltyp, Loc),
+                          Expression          => Left),
+                        Make_Object_Declaration (Loc,
+                          Defining_Identifier => T2,
+                          Object_Definition   => New_Occurrence_Of (Rtyp, Loc),
+                          Expression          => Right)),
+
+                      Expression =>
+                        Make_If_Expression (Loc,
+                          Expressions => New_List (
+                            Make_Compare
+                              (New_Occurrence_Of (T1, Loc),
+                               New_Occurrence_Of (T2, Loc)),
+                            New_Occurrence_Of (T1, Loc),
+                            New_Occurrence_Of (T2, Loc)))));
+               end;
+            end if;
+
+            Analyze_And_Resolve (N, Typ);
+         end;
+      end if;
+   end Expand_Min_Max_Attribute;
+
    ----------------------------------
    -- Expand_N_Attribute_Reference --
    ----------------------------------
@@ -3621,38 +3735,7 @@ package body Exp_Attr is
       ---------
 
       when Attribute_Max =>
-
-         --  Max is handled by the back end (except that static cases have
-         --  already been evaluated during semantic processing, but anyway
-         --  the back end should not count on this). The one bit of special
-         --  processing required in the normal case is that this attribute
-         --  typically generates conditionals in the code, so we must check
-         --  the relevant restriction.
-
-         Check_Restriction (No_Implicit_Conditionals, N);
-
-         --  In Modify_Tree_For_C mode, we rewrite as an if expression
-
-         if Modify_Tree_For_C then
-            declare
-               Loc   : constant Source_Ptr := Sloc (N);
-               Typ   : constant Entity_Id  := Etype (N);
-               Expr  : constant Node_Id    := First (Expressions (N));
-               Left  : constant Node_Id    := Relocate_Node (Expr);
-               Right : constant Node_Id    := Relocate_Node (Next (Expr));
-
-            begin
-               Rewrite (N,
-                 Make_If_Expression (Loc,
-                   Expressions => New_List (
-                     Make_Op_Ge (Loc,
-                       Left_Opnd  => Left,
-                       Right_Opnd => Right),
-                     Duplicate_Subexpr_No_Checks (Left),
-                     Duplicate_Subexpr_No_Checks (Right))));
-               Analyze_And_Resolve (N, Typ);
-            end;
-         end if;
+         Expand_Min_Max_Attribute (N);
 
       ----------------------------------
       -- Max_Size_In_Storage_Elements --
@@ -3733,7 +3816,7 @@ package body Exp_Attr is
 
       when Attribute_Mechanism_Code =>
 
-         --  We must replace the prefix in the renamed case
+         --  We must replace the prefix i the renamed case
 
          if Is_Entity_Name (Pref)
            and then Present (Alias (Entity (Pref)))
@@ -3746,38 +3829,7 @@ package body Exp_Attr is
       ---------
 
       when Attribute_Min =>
-
-         --  Min is handled by the back end (except that static cases have
-         --  already been evaluated during semantic processing, but anyway
-         --  the back end should not count on this). The one bit of special
-         --  processing required in the normal case is that this attribute
-         --  typically generates conditionals in the code, so we must check
-         --  the relevant restriction.
-
-         Check_Restriction (No_Implicit_Conditionals, N);
-
-         --  In Modify_Tree_For_C mode, we rewrite as an if expression
-
-         if Modify_Tree_For_C then
-            declare
-               Loc   : constant Source_Ptr := Sloc (N);
-               Typ   : constant Entity_Id  := Etype (N);
-               Expr  : constant Node_Id    := First (Expressions (N));
-               Left  : constant Node_Id    := Relocate_Node (Expr);
-               Right : constant Node_Id    := Relocate_Node (Next (Expr));
-
-            begin
-               Rewrite (N,
-                 Make_If_Expression (Loc,
-                   Expressions => New_List (
-                     Make_Op_Le (Loc,
-                       Left_Opnd  => Left,
-                       Right_Opnd => Right),
-                     Duplicate_Subexpr_No_Checks (Left),
-                     Duplicate_Subexpr_No_Checks (Right))));
-               Analyze_And_Resolve (N, Typ);
-            end;
-         end if;
+         Expand_Min_Max_Attribute (N);
 
       ---------
       -- Mod --
index d5bd8048fdc8f25c7ef9820ae91fa063ae05af1c..43dc9916ed66caa1d71a527f66358fdd1f845cc4 100644 (file)
@@ -5105,12 +5105,64 @@ package body Exp_Ch4 is
 
       --  Local variables
 
+      Loc : Source_Ptr;
       Act : Node_Id;
+      Def : Entity_Id;
+      Exp : Node_Id;
+      Nxt : Node_Id;
 
    --  Start of processing for Expand_N_Expression_With_Actions
 
    begin
+      --  Process the actions as described above
+
       Act := First (Actions (N));
+      while Present (Act) loop
+         Process_Single_Action (Act);
+         Next (Act);
+      end loop;
+
+      --  In Modify_Tree_For_C, we have trouble in C with object declarations
+      --  in the actions list (expressions are fine). So if we have an object
+      --  declaration, insert it higher in the tree, if necessary replacing it
+      --  with an assignment to capture initialization.
+
+      if Modify_Tree_For_C then
+         Act := First (Actions (N));
+         while Present (Act) loop
+            if Nkind (Act) = N_Object_Declaration then
+               Def := Defining_Identifier (Act);
+               Exp := Expression (Act);
+               Set_Constant_Present (Act, False);
+               Set_Expression (Act, Empty);
+               Insert_Action (N, Relocate_Node (Act));
+
+               Loc := Sloc (Act);
+
+               --  Expression present, rewrite as assignment, get next action
+
+               if Present (Exp) then
+                  Rewrite (Act,
+                    Make_Assignment_Statement (Loc,
+                      Name       => New_Occurrence_Of (Def, Loc),
+                      Expression => Exp));
+                  Next (Act);
+
+               --  No expression, remove action and move to next
+
+               else
+                  Nxt := Next (Act);
+                  Remove (Act);
+                  Act := Nxt;
+               end if;
+
+            --  Not an object declaration, move to next action
+
+            else
+               Next (Act);
+            end if;
+         end loop;
+      end if;
 
       --  Deal with case where there are no actions. In this case we simply
       --  rewrite the node with its expression since we don't need the actions
@@ -5121,17 +5173,8 @@ package body Exp_Ch4 is
       --  tree in cases like this. This raises a whole lot of issues of whether
       --  we have problems elsewhere, which will be addressed in the future???
 
-      if No (Act) then
+      if Is_Empty_List (Actions (N)) then
          Rewrite (N, Relocate_Node (Expression (N)));
-
-      --  Otherwise process the actions as described above
-
-      else
-         loop
-            Process_Single_Action (Act);
-            Next (Act);
-            exit when No (Act);
-         end loop;
       end if;
    end Expand_N_Expression_With_Actions;
 
index 901c922fd91581bac29e7789a8cbb574e3550d81..0a739370ae0d511334bd77d072239fb1864ed5fd 100644 (file)
@@ -75,6 +75,17 @@ package body Output is
       return Pos (Next_Col);
    end Column;
 
+   ----------------------
+   -- Delete_Last_Char --
+   ----------------------
+
+   procedure Delete_Last_Char is
+   begin
+      if Next_Col /= 1 then
+         Next_Col := Next_Col - 1;
+      end if;
+   end Delete_Last_Char;
+
    ------------------
    -- Flush_Buffer --
    ------------------
index 715a26a285e280868282dce0ade06440124c9adb..e4137c2add633f57819cec4aa2b6feacab79856d 100644 (file)
@@ -141,6 +141,10 @@ package Output is
    --  Returns last character written on the current line, or null if the
    --  current line is (so far) empty.
 
+   procedure Delete_Last_Char;
+   --  Deletes last character written on the current line, no effect if the
+   --  current line is (so far) empty.
+
    function Column return Pos;
    pragma Inline (Column);
    --  Returns the number of the column about to be written (e.g. a value of 1
index 7e4a9ee4e39e56bf784d2f02a589644e23d9a4c0..da7d76d573a3e7fe43d149ae3e3c5a6fa031e2b0 100644 (file)
@@ -144,6 +144,17 @@ package body Ch9 is
             end if;
 
             Parse_Decls_Begin_End (Task_Node);
+
+            --  The statement list of a task body needs to include at least a
+            --  null statement, so if a parsing error produces an empty list,
+            --  patch it now.
+
+            if
+              No (First (Statements (Handled_Statement_Sequence (Task_Node))))
+            then
+               Set_Statements (Handled_Statement_Sequence (Task_Node),
+                   New_List (Make_Null_Statement (Token_Ptr)));
+            end if;
          end if;
 
          return Task_Node;
index ed4a677e1815241ccfc88f7523e162bb1202a7ad..6bebed6a89dfd7d5979cc1e71829bc2a73e7628a 100644 (file)
@@ -4418,7 +4418,7 @@ package body Sem_Attr is
 
                --  Entities mentioned within the prefix of attribute 'Old must
                --  be global to the related postcondition. If this is not the
-               --  case, then the scope of the local entity is be nested within
+               --  case, then the scope of the local entity is nested within
                --  that of the subprogram.
 
                elsif Nkind (Nod) = N_Identifier
index 1f46ae2222b9353bb5bbb80c43999e4aa2e043e8..42c70764eb7325c80240ac9e31cb734dee8aceba 100644 (file)
@@ -21434,15 +21434,37 @@ package body Sem_Prag is
                   elsif Has_Non_Null_Refinement (Dep_Id) then
                      Has_Refined_State := True;
 
-                     if Is_Entity_Name (Ref_Output) then
-                        Ref_Id := Entity_Of (Ref_Output);
+                     --  Account for the case where a state with a non-null
+                     --  refinement matches a null output list:
+
+                     --    Refined_State   => (State_1 => (C1, C2),
+                     --                        State_2 => (C3, C4))
+                     --    Depends         => (State_1 => State_2)
+                     --    Refined_Depends => (null    => C3)
+
+                     if Nkind (Ref_Output) = N_Null
+                       and then Inputs_Match
+                                  (Dep_Clause  => Dep_Clause,
+                                   Ref_Clause  => Ref_Clause,
+                                   Post_Errors => False)
+                     then
+                        Has_Constituent := True;
 
-                        --  The output of the refinement clause is a valid
-                        --  constituent of the state. Remove the clause from
-                        --  the pool of candidates if both input lists match.
-                        --  Note that the search continues because one clause
-                        --  may have been normalized into multiple clauses as
-                        --  per the example above.
+                        --  Note that the search continues after the clause is
+                        --  removed from the pool of candidates because it may
+                        --  have been normalized into multiple simple clauses.
+
+                        Remove (Ref_Clause);
+
+                     --  Otherwise the output of the refinement clause must be
+                     --  a valid constituent of the state:
+
+                     --    Refined_State   => (State => (C1, C2))
+                     --    Depends         => (State => <input>)
+                     --    Refined_Depends => (C1    => <input>)
+
+                     elsif Is_Entity_Name (Ref_Output) then
+                        Ref_Id := Entity_Of (Ref_Output);
 
                         if Ekind_In (Ref_Id, E_Abstract_State, E_Variable)
                           and then Present (Encapsulating_State (Ref_Id))
@@ -21453,6 +21475,12 @@ package body Sem_Prag is
                                       Post_Errors => False)
                         then
                            Has_Constituent := True;
+
+                           --  Note that the search continues after the clause
+                           --  is removed from the pool of candidates because
+                           --  it may have been normalized into multiple simple
+                           --  clauses.
+
                            Remove (Ref_Clause);
                         end if;
                      end if;
@@ -21819,12 +21847,13 @@ package body Sem_Prag is
       begin
          --  Construct a list of all refinement inputs. Note that the input
          --  list is copied because the algorithm modifies its contents and
-         --  this should not be visible in Refined_Depends.
+         --  this should not be visible in Refined_Depends. The same applies
+         --  for a solitary input.
 
          if Nkind (Inputs) = N_Aggregate then
             Ref_Inputs := New_Copy_List (Expressions (Inputs));
          else
-            Ref_Inputs := New_List (Inputs);
+            Ref_Inputs := New_List (New_Copy (Inputs));
          end if;
 
          --  Depending on whether the original dependency clause mentions
index d3c3608ebbeec78a719a0db378d2c4da7c91fd67..4feed599c5d06f1fa501565314254e8975d108c0 100644 (file)
@@ -642,6 +642,13 @@ package Sinfo is
    --    Min and Max attributes are expanded into equivalent if expressions,
    --    dealing properly with side effect issues.
 
+   --    Mod for signed integer types is expanded into equivalent expressions
+   --    using Rem (which is % in C) and other C-available operators.
+
+   --    The Actions list of an Expression_With_Actions node has any object
+   --    declarations removed, so that it is composed only of expressions
+   --    (so that DO X,... Y IN Z can be represented as (X, .. Y, Z) in C).
+
    ------------------------------------
    -- Description of Semantic Fields --
    ------------------------------------
@@ -4127,6 +4134,11 @@ package Sinfo is
       --  and we are running in ELIMINATED mode, the operator node will be
       --  changed to be a call to the appropriate routine in System.Bignums.
 
+      --  Note: In Modify_Tree_For_C mode, we do not generate an N_Op_Mod node
+      --  for signed integer types (since there is no equivalent operator in
+      --  C). Instead we rewrite such an operation in terms of REM (which is
+      --  % in C) and other C-available operators.
+
       ------------------------------------
       -- 4.5.7  Conditional Expressions --
       ------------------------------------
@@ -7406,6 +7418,12 @@ package Sinfo is
       --  not a proper expression), and in the long term all cases of this
       --  idiom should instead use a new node kind N_Compound_Statement.
 
+      --  Note: In Modify_Tree_For_C, we eliminate declarations from the list
+      --  of actions, inserting them at the outer level. If we move an object
+      --  declaration with an initialization expression in this manner, then
+      --  the action is replaced by an appropriate assignment, otherwise it is
+      --  removed from the list of actions.
+
       --------------------
       -- Free Statement --
       --------------------