]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[multiple changes]
authorArnaud Charlet <charlet@gcc.gnu.org>
Fri, 18 Jul 2014 10:03:34 +0000 (12:03 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Fri, 18 Jul 2014 10:03:34 +0000 (12:03 +0200)
2014-07-18  Thomas Quinot  <quinot@adacore.com>

* g-memdum.adb, g-memdum.ads: Code clean ups.

2014-07-18  Hristian Kirtchev  <kirtchev@adacore.com>

* sem_prag.adb (Check_Dependency_Clause):
Update the comment on usage. Reimplement the mechanism which
attempts to match a single clause of Depends against one or
more clauses of Refined_Depends.
(Input_Match): Removed.
(Inputs_Match): Removed.
(Is_Self_Referential): Removed.
(Normalize_Clause): Update the call to Split_Multiple_Outputs.
(Normalize_Outputs): Rename variable Split to New_Claue and update
all its occurrences.
(Report_Extra_Clauses): Update the comment on usage.
(Split_Multiple_Outputs): Renamed to Normalize_Outputs.

2014-07-18  Gary Dismukes  <dismukes@adacore.com>

* i-cstrea.ads: Minor reformatting.

2014-07-18  Hristian Kirtchev  <kirtchev@adacore.com>

* exp_util.adb (Wrap_Statements_In_Block): Propagate both
secondary stack-related flags to the generated block.
* sem_ch5.adb (Analyze_Loop_Statement): Update the scope chain
once the loop is relocated in a block.

From-SVN: r212803

gcc/ada/ChangeLog
gcc/ada/exp_util.adb
gcc/ada/g-memdum.adb
gcc/ada/g-memdum.ads
gcc/ada/i-cstrea.ads
gcc/ada/sem_ch5.adb
gcc/ada/sem_prag.adb

index f136cc7337088d89cc591a6a54231d31f6263d82..504e7f82b24c7045ffa92943e68e765ed48e0e4d 100644 (file)
@@ -1,3 +1,33 @@
+2014-07-18  Thomas Quinot  <quinot@adacore.com>
+
+       * g-memdum.adb, g-memdum.ads: Code clean ups.
+
+2014-07-18  Hristian Kirtchev  <kirtchev@adacore.com>
+
+       * sem_prag.adb (Check_Dependency_Clause):
+       Update the comment on usage. Reimplement the mechanism which
+       attempts to match a single clause of Depends against one or
+       more clauses of Refined_Depends.
+       (Input_Match): Removed.
+       (Inputs_Match): Removed.
+       (Is_Self_Referential): Removed.
+       (Normalize_Clause): Update the call to Split_Multiple_Outputs.
+       (Normalize_Outputs): Rename variable Split to New_Claue and update
+       all its occurrences.
+       (Report_Extra_Clauses): Update the comment on usage.
+       (Split_Multiple_Outputs): Renamed to Normalize_Outputs.
+
+2014-07-18  Gary Dismukes  <dismukes@adacore.com>
+
+       * i-cstrea.ads: Minor reformatting.
+
+2014-07-18  Hristian Kirtchev  <kirtchev@adacore.com>
+
+       * exp_util.adb (Wrap_Statements_In_Block): Propagate both
+       secondary stack-related flags to the generated block.
+       * sem_ch5.adb (Analyze_Loop_Statement): Update the scope chain
+       once the loop is relocated in a block.
+
 2014-07-18  Robert Dewar  <dewar@adacore.com>
 
        * repinfo.ads: Add documentation on handling of back annotation
index 6db424c1708f3800494f937459644f0b34dc86a2..a94a11b5994cb90a3df41f57bc716bf2fc33935a 100644 (file)
@@ -6667,13 +6667,18 @@ package body Exp_Util is
 
          --  When wrapping the statements of an iterator loop, check whether
          --  the loop requires secondary stack management and if so, propagate
-         --  the flag to the block. This way the secondary stack is marked and
-         --  released at each iteration of the loop.
+         --  the appropriate flags to the block. This ensures that the cursor
+         --  is properly cleaned up at each iteration of the loop. Management
+         --  is not performed when the loop contains a return statement which
+         --  also uses the secondary stack as this will destroy the result
+         --  prematurely.
 
          Iter_Loop := Find_Enclosing_Iterator_Loop (Scop);
 
-         if Present (Iter_Loop) and then Uses_Sec_Stack (Iter_Loop) then
-            Set_Uses_Sec_Stack (Block_Id);
+         if Present (Iter_Loop) then
+            Set_Sec_Stack_Needed_For_Return
+              (Block_Id, Sec_Stack_Needed_For_Return (Iter_Loop));
+            Set_Uses_Sec_Stack (Block_Id, Uses_Sec_Stack (Iter_Loop));
          end if;
 
          return Block_Nod;
index 9d7b25c785fbf70ee393697cee397c6483f254ae..8aa24a72c79230c7d5f40061f51c4f39c465cdf1 100644 (file)
@@ -44,10 +44,18 @@ package body GNAT.Memory_Dump is
    -- Dump --
    ----------
 
+   procedure Dump
+     (Addr   : Address;
+      Count  : Natural)
+   is
+   begin
+      Dump (Addr, Count, Prefix => Absolute_Address);
+   end Dump;
+
    procedure Dump
      (Addr   : Address;
       Count  : Natural;
-      Prefix : Prefix_Type := Absolute_Address)
+      Prefix : Prefix_Type)
    is
       Ctr : Natural := Count;
       --  Count of bytes left to output
index 840fc92b5c27fe26e51973370d58630d371bc02c..7f9951b1e06f19e248908cba73f62765a32b0999 100644 (file)
@@ -42,20 +42,36 @@ package GNAT.Memory_Dump is
 
    procedure Dump
      (Addr   : System.Address;
-      Count  : Natural;
-      Prefix : Prefix_Type := Absolute_Address);
+      Count  : Natural);
    --  Dumps indicated number (Count) of bytes, starting at the address given
    --  by Addr. The coding of this routine in its current form assumes the case
    --  of a byte addressable machine (and is therefore inapplicable to machines
    --  like the AAMP, where the storage unit is not 8 bits). The output is one
    --  or more lines in the following format, which is for the case of 32-bit
    --  addresses (64-bit addresses are handled appropriately):
-   --
+
    --    0234_3368: 66 67 68 . . .  73 74 75 "fghijklmnopqstuv"
-   --
+
    --  All but the last line have 16 bytes. A question mark is used in the
    --  string data to indicate a non-printable character.
-   --
-   --  Please document Prefix ???
+
+   procedure Dump
+     (Addr   : System.Address;
+      Count  : Natural;
+      Prefix : Prefix_Type);
+   --  Same as above, but allows the selection of different line formats.
+   --  If Prefix is set to Absolute_Address, the output is identical to the
+   --  above version, each line starting with the absolute address of the
+   --  first dumped storage element.
+
+   --  If Prefix is set to Offset, then instead each line starts with the
+   --  indication of the offset relative to Addr:
+
+   --    00: 66 67 68 . . .  73 74 75 "fghijklmnopqstuv"
+
+   --  Finally if Prefix is set to None, the prefix is suppressed altogether,
+   --  and only the memory contents are displayed:
+
+   --    66 67 68 . . .  73 74 75 "fghijklmnopqstuv"
 
 end GNAT.Memory_Dump;
index 67ca62f6e953c7df87e6a7f8383ea6b2339871f9..dc337878031d402995053ea826859ee29fc9c59a 100644 (file)
@@ -230,9 +230,9 @@ package Interfaces.C_Streams is
    procedure set_text_mode   (handle : int);
 
    --  set_wide_text_mode is as set_text_mode but switches the translation to
-   --  16-bits wide-character instead of 8-bits character. Again this routine
-   --  has not effect if text_translation_required is false. On Windows this
-   --  is used to have proper 16-bits wide string output on the console for
+   --  16-bit wide-character instead of 8-bit character. Again, this routine
+   --  has no effect if text_translation_required is false. On Windows this
+   --  is used to have proper 16-bit wide-string output on the console for
    --  example.
 
    procedure set_wide_text_mode (handle : int);
index d90a7e534cb2077ec6cbb9aa1b34a9c5dc06ad95..40034e788bf13489f991cb7e94c3d51de361d098 100644 (file)
@@ -2885,6 +2885,12 @@ package body Sem_Ch5 is
 
             Add_Block_Identifier (Block_Nod, Block_Id);
 
+            --  Fix the loop scope once the loop statement is relocated inside
+            --  the block, otherwise the loop and the block end up sharing the
+            --  same parent scope.
+
+            Set_Scope (Ent, Block_Id);
+
             --  The expansion of iterator loops generates an iterator in order
             --  to traverse the elements of a container:
 
index c36a8fb6d0fcfe72991344e631f18555d2ae3ac5..73a4f87484933a0d44699d9480c9dbc7e8595c74 100644 (file)
@@ -1340,7 +1340,7 @@ package body Sem_Prag is
          --  Flag Multiple should be set when Output comes from a list with
          --  multiple items.
 
-         procedure Split_Multiple_Outputs;
+         procedure Normalize_Outputs;
          --  If Clause contains more than one output, split the clause into
          --  multiple clauses with a single output. All new clauses are added
          --  after Clause.
@@ -1530,20 +1530,18 @@ package body Sem_Prag is
             end if;
          end Create_Or_Modify_Clause;
 
-         ----------------------------
-         -- Split_Multiple_Outputs --
-         ----------------------------
+         -----------------------
+         -- Normalize_Outputs --
+         -----------------------
 
-         procedure Split_Multiple_Outputs is
+         procedure Normalize_Outputs is
             Inputs      : constant Node_Id    := Expression (Clause);
             Loc         : constant Source_Ptr := Sloc (Clause);
             Outputs     : constant Node_Id    := First (Choices (Clause));
             Last_Output : Node_Id;
+            New_Clause  : Node_Id;
             Next_Output : Node_Id;
             Output      : Node_Id;
-            Split       : Node_Id;
-
-         --  Start of processing for Split_Multiple_Outputs
 
          begin
             --  Multiple outputs appear as an aggregate. Nothing to do when
@@ -1576,7 +1574,7 @@ package body Sem_Prag is
                      --  Generate a clause of the form:
                      --    (Output => Inputs)
 
-                     Split :=
+                     New_Clause :=
                        Make_Component_Association (Loc,
                          Choices    => New_List (Output),
                          Expression => New_Copy_Tree (Inputs));
@@ -1585,14 +1583,14 @@ package body Sem_Prag is
                      --  already been analyzed. There is not need to reanalyze
                      --  them.
 
-                     Set_Analyzed (Split);
-                     Insert_After (Clause, Split);
+                     Set_Analyzed (New_Clause);
+                     Insert_After (Clause, New_Clause);
                   end if;
 
                   Output := Next_Output;
                end loop;
             end if;
-         end Split_Multiple_Outputs;
+         end Normalize_Outputs;
 
          --  Local variables
 
@@ -1652,7 +1650,7 @@ package body Sem_Prag is
          --  Split a clause with multiple outputs into multiple clauses with a
          --  single output.
 
-         Split_Multiple_Outputs;
+         Normalize_Outputs;
       end Normalize_Clause;
 
       --  Local variables
@@ -21831,6 +21829,9 @@ package body Sem_Prag is
       Depends      : Node_Id;
       --  The corresponding Depends pragma along with its clauses
 
+      Refined_States : Elist_Id := No_Elist;
+      --  A list containing all successfully refined states
+
       Refinements : List_Id := No_List;
       --  The clauses of pragma Refined_Depends
 
@@ -21838,706 +21839,400 @@ package body Sem_Prag is
       --  The entity of the subprogram subject to pragma Refined_Depends
 
       procedure Check_Dependency_Clause (Dep_Clause : Node_Id);
-      --  Verify the legality of a single clause
-
-      function Input_Match
-        (Dep_Input   : Node_Id;
-         Ref_Inputs  : List_Id;
-         Post_Errors : Boolean) return Boolean;
-      --  Determine whether input Dep_Input matches one of inputs found in list
-      --  Ref_Inputs. If flag Post_Errors is set, the routine reports missed or
-      --  extra input items.
-
-      function Inputs_Match
-        (Dep_Clause  : Node_Id;
-         Ref_Clause  : Node_Id;
-         Post_Errors : Boolean) return Boolean;
-      --  Determine whether the inputs of Depends clause Dep_Clause match those
-      --  of refinement clause Ref_Clause. If flag Post_Errors is set, then the
-      --  routine reports missed or extra input items.
-
-      function Is_Self_Referential (Item_Id : Entity_Id) return Boolean;
-      --  Determine whether a formal parameter, variable or state denoted by
-      --  Item_Id appears both as input and an output in a single clause of
-      --  pragma Depends.
+      --  Try to match a single dependency clause Dep_Clause against one or
+      --  more refinement clauses found in list Refinements. Each successful
+      --  match eliminates at least one refinement clause from Refinements.
+
+      procedure Normalize_Clauses (Clauses : List_Id);
+      --  Given a list of dependence or refinement clauses Clauses, normalize
+      --  each clause by creating multiple dependencies with exactly one input
+      --  and one output.
 
       procedure Report_Extra_Clauses;
-      --  Emit an error for each extra clause the appears in Refined_Depends
+      --  Emit an error for each extra clause found in list Refinements
 
       -----------------------------
       -- Check_Dependency_Clause --
       -----------------------------
 
       procedure Check_Dependency_Clause (Dep_Clause : Node_Id) is
-         Dep_Output      : constant Node_Id := First (Choices (Dep_Clause));
-         Dep_Id          : Entity_Id;
-         Matching_Clause : Node_Id := Empty;
-         Next_Ref_Clause : Node_Id;
-         Ref_Clause      : Node_Id;
-         Ref_Id          : Entity_Id;
-         Ref_Output      : Node_Id;
-
-         Has_Constituent : Boolean := False;
-         --  Flag set when the refinement output list contains at least one
-         --  constituent of the state denoted by Dep_Id.
+         Dep_Input  : constant Node_Id := Expression (Dep_Clause);
+         Dep_Output : constant Node_Id := First (Choices (Dep_Clause));
+
+         function Is_In_Out_State_Clause return Boolean;
+         --  Determine whether dependence clause Dep_Clause denotes an abstract
+         --  state that depends on itself (State => State).
+
+         procedure Match_Items
+           (Dep_Item : Node_Id;
+            Ref_Item : Node_Id;
+            Matched  : out Boolean);
+         --  Try to match dependence item Dep_Item against refinement item
+         --  Ref_Item. To match against a possible null refinement (see 2, 7),
+         --  set Ref_Item to Empty. Flag Matched is set to True when one of
+         --  the following conformance scenarios is in effect:
+         --    1) Both items denote null
+         --    2) Dep_Item denotes null and Ref_Item is Empty (special case)
+         --    3) Both items denote attribute 'Result
+         --    4) Both items denote the same formal parameter
+         --    5) Both items denote the same variable
+         --    6) Dep_Item is an abstract state with visible null refinement
+         --       and Ref_Item denotes null.
+         --    7) Dep_Item is an abstract state with visible null refinement
+         --       and Ref_Item is Empty (special case).
+         --    8) Dep_Item is an abstract state with visible non-null
+         --       refinement and Ref_Item denotes one of its constituents.
+         --    9) Dep_Item is an abstract state without a visible refinement
+         --       and Ref_Item denotes the same state.
+         --  When scenario 8 is in effect, the entity of the abstract state
+         --  denoted by Dep_Item is added to list Refined_States.
 
-         Has_Null_State : Boolean := False;
-         --  Flag set when the output of clause Dep_Clause is a state with a
-         --  null refinement.
+         ----------------------------
+         -- Is_In_Out_State_Clause --
+         ----------------------------
 
-         Has_Refined_State : Boolean := False;
-         --  Flag set when the output of clause Dep_Clause is a state with
-         --  visible refinement.
+         function Is_In_Out_State_Clause return Boolean is
+            Dep_Input_Id  : Entity_Id;
+            Dep_Output_Id : Entity_Id;
 
-      begin
-         --  The analysis of pragma Depends should produce normalized clauses
-         --  with exactly one output. This is important because output items
-         --  are unique in the whole dependence relation and can be used as
-         --  keys.
+         begin
+            --  Detect the following clause:
+            --    State => State
 
-         pragma Assert (No (Next (Dep_Output)));
+            if Is_Entity_Name (Dep_Input)
+              and then Is_Entity_Name (Dep_Output)
+            then
+               --  Handle abstract views generated for limited with clauses
 
-         --  Inspect all clauses of Refined_Depends and attempt to match the
-         --  output of Dep_Clause against an output from the refinement clauses
-         --  set.
+               Dep_Input_Id  := Available_View (Entity_Of (Dep_Input));
+               Dep_Output_Id := Available_View (Entity_Of (Dep_Output));
 
-         Ref_Clause := First (Refinements);
-         while Present (Ref_Clause) loop
-            Matching_Clause := Empty;
+               return
+                 Ekind (Dep_Input_Id) = E_Abstract_State
+                   and then Dep_Input_Id = Dep_Output_Id;
+            else
+               return False;
+            end if;
+         end Is_In_Out_State_Clause;
 
-            --  Store the next clause now because a match will trim the list of
-            --  refinement clauses and this side effect should not be visible
-            --  in pragma Refined_Depends.
+         -----------------
+         -- Match_Items --
+         -----------------
 
-            Next_Ref_Clause := Next (Ref_Clause);
+         procedure Match_Items
+           (Dep_Item : Node_Id;
+            Ref_Item : Node_Id;
+            Matched  : out Boolean)
+         is
+            Dep_Item_Id : Entity_Id;
+            Ref_Item_Id : Entity_Id;
 
-            --  The analysis of pragma Refined_Depends should produce
-            --  normalized clauses with exactly one output.
+         begin
+            --  Assume that the two items do not match
 
-            Ref_Output := First (Choices (Ref_Clause));
-            pragma Assert (No (Next (Ref_Output)));
+            Matched := False;
 
-            --  Two null output lists match if their inputs match
+            --  A null matches null or Empty (special case)
 
-            if Nkind (Dep_Output) = N_Null
-              and then Nkind (Ref_Output) = N_Null
+            if Nkind (Dep_Item) = N_Null
+              and then (No (Ref_Item) or else Nkind (Ref_Item) = N_Null)
             then
-               Matching_Clause := Ref_Clause;
-               exit;
+               Matched := True;
 
-            --  Two function 'Result attributes match if their inputs match.
-            --  Note that there is no need to compare the two prefixes because
-            --  the attributes cannot denote anything but the related function.
+            --  Attribute 'Result matches attribute 'Result
 
-            elsif Is_Attribute_Result (Dep_Output)
-              and then Is_Attribute_Result (Ref_Output)
+            elsif Is_Attribute_Result (Dep_Item)
+              and then Is_Attribute_Result (Dep_Item)
             then
-               Matching_Clause := Ref_Clause;
-               exit;
-
-            --  The remaining cases are formal parameters, variables and states
-
-            elsif Is_Entity_Name (Dep_Output) then
-
-               --  Handle abstract views of states and variables generated for
-               --  limited with clauses.
-
-               Dep_Id := Available_View (Entity_Of (Dep_Output));
+               Matched := True;
 
-               if Ekind (Dep_Id) = E_Abstract_State then
+            --  Abstract states, formal parameters and variables
 
-                  --  A state with a null refinement matches either a null
-                  --  output list or nothing at all (no clause):
+            elsif Is_Entity_Name (Dep_Item) then
 
-                  --    Refined_State   => (State => null)
+               --  Handle abstract views generated for limited with clauses
 
-                  --  No clause
+               Dep_Item_Id := Available_View (Entity_Of (Dep_Item));
 
-                  --    Depends         => (State => null)
-                  --    Refined_Depends =>  null               --  OK
+               if Ekind (Dep_Item_Id) = E_Abstract_State then
 
-                  --  Null output list
+                  --  An abstract state with visible null refinement matches
+                  --  null or Empty (special case).
 
-                  --    Depends         => (State => <input>)
-                  --    Refined_Depends => (null  => <input>)  --  OK
-
-                  if Has_Null_Refinement (Dep_Id) then
-                     Has_Null_State := True;
-
-                     --  When a state with null refinement matches a null
-                     --  output, compare their inputs.
-
-                     if Nkind (Ref_Output) = N_Null then
-                        Matching_Clause := Ref_Clause;
-                     end if;
-
-                     exit;
-
-                  --  The state has a non-null refinement in which case the
-                  --  match is based on constituents and inputs. A state with
-                  --  multiple output constituents may match multiple clauses:
-
-                  --    Refined_State   => (State => (C1, C2))
-                  --    Depends         => (State => <input>)
-                  --    Refined_Depends => ((C1, C2) => <input>)
-
-                  --  When normalized, the above becomes:
-
-                  --    Refined_Depends => (C1 => <input>,
-                  --                        C2 => <input>)
-
-                  elsif Has_Non_Null_Refinement (Dep_Id) then
-                     Has_Refined_State := True;
-
-                     --  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;
-
-                        --  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:
+                  if Has_Null_Refinement (Dep_Item_Id)
+                    and then (No (Ref_Item) or else Nkind (Ref_Item) = N_Null)
+                  then
+                     Matched := True;
 
-                     --    Refined_State   => (State => (C1, C2))
-                     --    Depends         => (State => <input>)
-                     --    Refined_Depends => (C1    => <input>)
+                  --  An abstract state with visible non-null refinement
+                  --  matches one of its constituents.
 
-                     elsif Is_Entity_Name (Ref_Output) then
-                        Ref_Id := Entity_Of (Ref_Output);
+                  elsif Has_Non_Null_Refinement (Dep_Item_Id) then
+                     if Is_Entity_Name (Ref_Item) then
+                        Ref_Item_Id := Entity_Of (Ref_Item);
 
-                        if Ekind_In (Ref_Id, E_Abstract_State, E_Variable)
-                          and then Present (Encapsulating_State (Ref_Id))
-                          and then Encapsulating_State (Ref_Id) = Dep_Id
-                          and then Inputs_Match
-                                     (Dep_Clause  => Dep_Clause,
-                                      Ref_Clause  => Ref_Clause,
-                                      Post_Errors => False)
+                        if Ekind_In (Ref_Item_Id, E_Abstract_State, E_Variable)
+                          and then Present (Encapsulating_State (Ref_Item_Id))
+                          and then Encapsulating_State (Ref_Item_Id) =
+                                     Dep_Item_Id
                         then
-                           Has_Constituent := True;
+                           --  Record the successfully refined state
 
-                           --  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.
+                           if not Contains (Refined_States, Dep_Item_Id) then
+                              Add_Item (Dep_Item_Id, Refined_States);
+                           end if;
 
-                           Remove (Ref_Clause);
+                           Matched := True;
                         end if;
                      end if;
 
-                  --  The abstract view of a state matches is corresponding
-                  --  non-abstract view:
-
-                  --    Depends         => (Lim_Pack.State => <input>)
-                  --    Refined_Depends => (State          => <input>)
+                  --  An abstract state without a visible refinement matches
+                  --  itself.
 
-                  elsif Is_Entity_Name (Ref_Output)
-                    and then Entity_Of (Ref_Output) = Dep_Id
+                  elsif Is_Entity_Name (Ref_Item)
+                    and then Entity_Of (Ref_Item) = Dep_Item_Id
                   then
-                     Matching_Clause := Ref_Clause;
-                     exit;
+                     Matched := True;
                   end if;
 
-               --  Formal parameters and variables match if their inputs match
+               --  A formal parameter or a variable matches itself
 
-               elsif Is_Entity_Name (Ref_Output)
-                 and then Entity_Of (Ref_Output) = Dep_Id
+               elsif Is_Entity_Name (Ref_Item)
+                 and then Entity_Of (Ref_Item) = Dep_Item_Id
                then
-                  Matching_Clause := Ref_Clause;
-                  exit;
+                  Matched := True;
                end if;
             end if;
-
-            Ref_Clause := Next_Ref_Clause;
-         end loop;
-
-         --  Handle the case where pragma Depends contains one or more clauses
-         --  that only mention states with null refinements. In that case the
-         --  corresponding pragma Refined_Depends may have a null relation.
-
-         --    Refined_State   => (State => null)
-         --    Depends         => (State => null)
-         --    Refined_Depends =>  null            --  OK
-
-         --  Another instance of the same scenario occurs when the list of
-         --  refinements has been depleted while processing previous clauses.
-
-         if Is_Entity_Name (Dep_Output)
-           and then (No (Refinements) or else Is_Empty_List (Refinements))
-         then
-            Dep_Id := Entity_Of (Dep_Output);
-
-            if Ekind (Dep_Id) = E_Abstract_State
-              and then Has_Null_Refinement (Dep_Id)
-            then
-               Has_Null_State := True;
-            end if;
-         end if;
-
-         --  The above search produced a match based on unique output. Ensure
-         --  that the inputs match as well and if they do, remove the clause
-         --  from the pool of candidates.
-
-         if Present (Matching_Clause) then
-            if Inputs_Match
-                 (Ref_Clause  => Ref_Clause,
-                  Dep_Clause  => Matching_Clause,
-                  Post_Errors => True)
-            then
-               Remove (Matching_Clause);
-            end if;
-
-         --  A state with a visible refinement was matched against one or
-         --  more clauses containing appropriate constituents.
-
-         elsif Has_Constituent then
-            null;
-
-         --  A state with a null refinement did not warrant a clause
-
-         elsif Has_Null_State then
-            null;
-
-         --  The dependence relation of pragma Refined_Depends does not contain
-         --  a matching clause, emit an error.
-
-         else
-            SPARK_Msg_NE
-              ("dependence clause of subprogram & has no matching refinement "
-               & "in body", Ref_Clause, Spec_Id);
-
-            if Has_Refined_State then
-               SPARK_Msg_N
-                 ("\check the use of constituents in dependence refinement",
-                  Ref_Clause);
-            end if;
-         end if;
-      end Check_Dependency_Clause;
-
-      -----------------
-      -- Input_Match --
-      -----------------
-
-      function Input_Match
-        (Dep_Input   : Node_Id;
-         Ref_Inputs  : List_Id;
-         Post_Errors : Boolean) return Boolean
-      is
-         procedure Match_Error (Msg : String; N : Node_Id);
-         --  Emit a matching error if flag Post_Errors is set
-
-         -----------------
-         -- Match_Error --
-         -----------------
-
-         procedure Match_Error (Msg : String; N : Node_Id) is
-         begin
-            if Post_Errors then
-               SPARK_Msg_N (Msg, N);
-            end if;
-         end Match_Error;
+         end Match_Items;
 
          --  Local variables
 
-         Dep_Id         : Node_Id;
-         Next_Ref_Input : Node_Id;
-         Ref_Id         : Entity_Id;
-         Ref_Input      : Node_Id;
-
-         Has_Constituent : Boolean := False;
-         --  Flag set when the refinement input list contains at least one
-         --  constituent of the state denoted by Dep_Id.
-
-         Has_Null_State : Boolean := False;
-         --  Flag set when the dependency input is a state with a visible null
-         --  refinement.
-
-         Has_Refined_State : Boolean := False;
-         --  Flag set when the dependency input is a state with visible non-
-         --  null refinement.
+         Clause_Matched  : Boolean := False;
+         Dummy           : Boolean := False;
+         Inputs_Match    : Boolean;
+         Next_Ref_Clause : Node_Id;
+         Outputs_Match   : Boolean;
+         Ref_Clause      : Node_Id;
+         Ref_Input       : Node_Id;
+         Ref_Output      : Node_Id;
 
-      --  Start of processing for Input_Match
+      --  Start of processing for Check_Dependency_Clause
 
       begin
-         --  Match a null input with another null input
-
-         if Nkind (Dep_Input) = N_Null then
-            Ref_Input := First (Ref_Inputs);
-
-            --  Remove the matching null from the pool of candidates
-
-            if Nkind (Ref_Input) = N_Null then
-               Remove (Ref_Input);
-               return True;
-
-            else
-               Match_Error
-                 ("null input cannot be matched in corresponding refinement "
-                  & "clause", Dep_Input);
-            end if;
-
-         --  Remaining cases are formal parameters, variables, and states
-
-         else
-            --  Handle abstract views of states and variables generated for
-            --  limited with clauses.
-
-            Dep_Id := Available_View (Entity_Of (Dep_Input));
-
-            --  Inspect all inputs of the refinement clause and attempt to
-            --  match against the inputs of the dependence clause.
-
-            Ref_Input := First (Ref_Inputs);
-            while Present (Ref_Input) loop
-
-               --  Store the next input now because a match will remove it from
-               --  the list.
-
-               Next_Ref_Input := Next (Ref_Input);
-
-               if Ekind (Dep_Id) = E_Abstract_State then
-
-                  --  A state with a null refinement matches either a null
-                  --  input list or nothing at all (no input):
-
-                  --    Refined_State   => (State => null)
-
-                  --  No input
-
-                  --    Depends         => (<output> => (State, Input))
-                  --    Refined_Depends => (<output> => Input)  --  OK
-
-                  --  Null input list
-
-                  --    Depends         => (<output> => State)
-                  --    Refined_Depends => (<output> => null)   --  OK
-
-                  if Has_Null_Refinement (Dep_Id) then
-                     Has_Null_State := True;
-
-                     --  Remove the matching null from the pool of candidates
+         --  Examine all refinement clauses and compare them against the
+         --  dependence clause.
 
-                     if Nkind (Ref_Input) = N_Null then
-                        Remove (Ref_Input);
-                     end if;
-
-                     return True;
-
-                  --  The state has a non-null refinement in which case remove
-                  --  all the matching constituents of the state:
-
-                  --    Refined_State   => (State    => (C1, C2))
-                  --    Depends         => (<output> =>  State)
-                  --    Refined_Depends => (<output> => (C1, C2))
-
-                  elsif Has_Non_Null_Refinement (Dep_Id) then
-                     Has_Refined_State := True;
-
-                     --  A state with a visible non-null refinement may have a
-                     --  null input_list only when it is self referential.
-
-                     --    Refined_State   => (State => (C1, C2))
-                     --    Depends         => (State => State)
-                     --    Refined_Depends => (C2 => null)  --  OK
-
-                     if Nkind (Ref_Input) = N_Null
-                       and then Is_Self_Referential (Dep_Id)
-                     then
-                        --  Remove the null from the pool of candidates. Note
-                        --  that the search continues because the state may be
-                        --  represented by multiple constituents.
+         Ref_Clause := First (Refinements);
+         while Present (Ref_Clause) loop
+            Next_Ref_Clause := Next (Ref_Clause);
 
-                        Has_Constituent := True;
-                        Remove (Ref_Input);
+            --  Obtain the attributes of the current refinement clause
 
-                     --  Ref_Input is an entity name
+            Ref_Input  := Expression (Ref_Clause);
+            Ref_Output := First (Choices (Ref_Clause));
 
-                     elsif Is_Entity_Name (Ref_Input) then
-                        Ref_Id := Entity_Of (Ref_Input);
+            --  The current refinement clause matches the dependence clause
+            --  when both outputs match and both inputs match. See routine
+            --  Match_Items for all possible conformance scenarios.
 
-                        --  The input of the refinement clause is a valid
-                        --  constituent of the state. Remove the input from the
-                        --  pool of candidates. Note that the search continues
-                        --  because the state may be represented by multiple
-                        --  constituents.
+            --    Depends           Dep_Output => Dep_Input
+            --                          ^             ^
+            --                        match ?       match ?
+            --                          v             v
+            --    Refined_Depends   Ref_Output => Ref_Input
 
-                        if Ekind_In (Ref_Id, E_Abstract_State,
-                                             E_Variable)
-                          and then Present (Encapsulating_State (Ref_Id))
-                          and then Encapsulating_State (Ref_Id) = Dep_Id
-                        then
-                           Has_Constituent := True;
-                           Remove (Ref_Input);
-                        end if;
-                     end if;
+            Match_Items
+              (Dep_Item => Dep_Input,
+               Ref_Item => Ref_Input,
+               Matched  => Inputs_Match);
 
-                  --  The abstract view of a state matches its corresponding
-                  --  non-abstract view:
+            Match_Items
+              (Dep_Item => Dep_Output,
+               Ref_Item => Ref_Output,
+               Matched  => Outputs_Match);
 
-                  --    Depends         => (<output> => Lim_Pack.State)
-                  --    Refined_Depends => (<output> => State)
+            --  An In_Out state clause may be matched against a refinement with
+            --  a null input or null output as long as the non-null side of the
+            --  relation contains a valid constituent of the In_Out_State.
 
-                  elsif Is_Entity_Name (Ref_Input)
-                    and then Entity_Of (Ref_Input) = Dep_Id
-                  then
-                     Remove (Ref_Input);
-                     return True;
-                  end if;
+            if Is_In_Out_State_Clause then
 
-               --  Formal parameters and variables are matched on entities. If
-               --  this is the case, remove the input from the candidate list.
+               --  Depends         => (State => State)
+               --  Refined_Depends => (null => Constit)  --  OK
 
-               elsif Is_Entity_Name (Ref_Input)
-                 and then Entity_Of (Ref_Input) = Dep_Id
+               if Inputs_Match
+                 and then not Outputs_Match
+                 and then Nkind (Ref_Output) = N_Null
                then
-                  Remove (Ref_Input);
-                  return True;
+                  Outputs_Match := True;
                end if;
 
-               Ref_Input := Next_Ref_Input;
-            end loop;
+               --  Depends         => (State => State)
+               --  Refined_Depends => (Constit => null)  --  OK
 
-            --  When a state with a null refinement appears as the last input,
-            --  it matches nothing:
-
-            --    Refined_State   => (State => null)
-            --    Depends         => (<output> => (Input, State))
-            --    Refined_Depends => (<output> => Input)  --  OK
-
-            if Ekind (Dep_Id) = E_Abstract_State
-              and then Has_Null_Refinement (Dep_Id)
-              and then No (Ref_Input)
-            then
-               Has_Null_State := True;
+               if not Inputs_Match
+                 and then Outputs_Match
+                 and then Nkind (Ref_Input) = N_Null
+               then
+                  Inputs_Match := True;
+               end if;
             end if;
-         end if;
-
-         --  A state with visible refinement was matched against one or more of
-         --  its constituents.
-
-         if Has_Constituent then
-            return True;
-
-         --  A state with a null refinement matched null or nothing
-
-         elsif Has_Null_State then
-            return True;
 
-         --  The input of a dependence clause does not have a matching input in
-         --  the refinement clause, emit an error.
+            --  The current refinement clause is legally constructed following
+            --  the rules in SPARK RM 7.2.5, therefore it can be removed from
+            --  the pool of candidates. The seach continues because a single
+            --  dependence clause may have multiple matching refinements.
 
-         else
-            Match_Error
-              ("input cannot be matched in corresponding refinement clause",
-               Dep_Input);
-
-            if Has_Refined_State then
-               Match_Error
-                 ("\check the use of constituents in dependence refinement",
-                  Dep_Input);
+            if Inputs_Match and then Outputs_Match then
+               Clause_Matched := True;
+               Remove (Ref_Clause);
             end if;
 
-            return False;
-         end if;
-      end Input_Match;
-
-      ------------------
-      -- Inputs_Match --
-      ------------------
-
-      function Inputs_Match
-        (Dep_Clause  : Node_Id;
-         Ref_Clause  : Node_Id;
-         Post_Errors : Boolean) return Boolean
-      is
-         Ref_Inputs : List_Id;
-         --  The input list of the refinement clause
+            Ref_Clause := Next_Ref_Clause;
+         end loop;
 
-         procedure Report_Extra_Inputs;
-         --  Emit errors for all extra inputs that appear in Ref_Inputs
+         --  Depending on the order or composition of refinement clauses, an
+         --  In_Out state clause may not be directly refinable.
 
-         -------------------------
-         -- Report_Extra_Inputs --
-         -------------------------
+         --    Depends         => ((Output, State) => (Input, State))
+         --    Refined_State   => (State => (Constit_1, Constit_2))
+         --    Refined_Depends => (Constit_1 => Input, Output => Constit_2)
 
-         procedure Report_Extra_Inputs is
-            Input : Node_Id;
+         --  Matching normalized clause (State => State) fails because there is
+         --  no direct refinement capable of satisfying this relation. Another
+         --  similar case arises when clauses (Constit_1 => Input) and (Output
+         --  => Constit_2) are matched first, leaving no candidates for clause
+         --  (State => State). Both scenarios are legal as long as one of the
+         --  previous clauses mentioned a valid constituent of State.
 
-         begin
-            if Present (Ref_Inputs) and then Post_Errors then
-               Input := First (Ref_Inputs);
-               while Present (Input) loop
-                  SPARK_Msg_N
-                    ("unmatched or extra input in refinement clause", Input);
-
-                  Next (Input);
-               end loop;
-            end if;
-         end Report_Extra_Inputs;
+         if not Clause_Matched
+           and then Is_In_Out_State_Clause
+           and then Contains
+                      (Refined_States, Available_View (Entity_Of (Dep_Input)))
+         then
+            Clause_Matched := True;
+         end if;
 
-         --  Local variables
+         --  At this point either all refinement clauses have been examined or
+         --  pragma Refined_Depends contains a solitary null. Only an abstract
+         --  state with null refinement can possibly match these cases.
 
-         Dep_Inputs : constant Node_Id := Expression (Dep_Clause);
-         Inputs     : constant Node_Id := Expression (Ref_Clause);
-         Dep_Input  : Node_Id;
-         Result     : Boolean;
+         --    Depends         => (State => null)
+         --    Refined_State   => (State => null)
+         --    Refined_Depends =>  null            --  OK
 
-      --  Start of processing for Inputs_Match
+         if not Clause_Matched then
+            Match_Items
+              (Dep_Item => Dep_Input,
+               Ref_Item => Empty,
+               Matched  => Inputs_Match);
 
-      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. The same applies
-         --  for a solitary input.
+            Match_Items
+              (Dep_Item => Dep_Output,
+               Ref_Item => Empty,
+               Matched  => Outputs_Match);
 
-         if Nkind (Inputs) = N_Aggregate then
-            Ref_Inputs := New_Copy_List (Expressions (Inputs));
-         else
-            Ref_Inputs := New_List (New_Copy (Inputs));
+            Clause_Matched := Inputs_Match and Outputs_Match;
          end if;
 
-         --  Depending on whether the original dependency clause mentions
-         --  states with visible refinement, the corresponding refinement
-         --  clause may differ greatly in structure and contents:
+         --  If the contents of Refined_Depends are legal, then the current
+         --  dependence clause should be satisfied either by an explicit match
+         --  or by one of the special cases.
 
-         --  State with null refinement
+         if not Clause_Matched then
+            SPARK_Msg_NE
+              ("dependence clause of subprogram & has no matching refinement "
+               & "in body", Dep_Clause, Spec_Id);
+         end if;
+      end Check_Dependency_Clause;
 
-         --    Refined_State   => (State    => null)
-         --    Depends         => (<output> => State)
-         --    Refined_Depends => (<output> => null)
+      -----------------------
+      -- Normalize_Clauses --
+      -----------------------
 
-         --    Depends         => (<output> => (State, Input))
-         --    Refined_Depends => (<output> => Input)
+      procedure Normalize_Clauses (Clauses : List_Id) is
+         procedure Normalize_Inputs (Clause : Node_Id);
+         --  Normalize clause Clause by creating multiple clauses for each
+         --  input item of Clause. It is assumed that Clause has exactly one
+         --  output. The transformation is as follows:
+         --
+         --    Output => (Input_1, Input_2)      --  original
+         --
+         --    Output => Input_1                 --  normalizations
+         --    Output => Input_2
 
-         --    Depends         => (<output> => (Input_1, State, Input_2))
-         --    Refined_Depends => (<output> => (Input_1, Input_2))
+         ----------------------
+         -- Normalize_Inputs --
+         ----------------------
 
-         --  State with non-null refinement
+         procedure Normalize_Inputs (Clause : Node_Id) is
+            Inputs     : constant Node_Id    := Expression (Clause);
+            Loc        : constant Source_Ptr := Sloc (Clause);
+            Output     : constant List_Id    := Choices (Clause);
+            Last_Input : Node_Id;
+            Input      : Node_Id;
+            New_Clause : Node_Id;
+            Next_Input : Node_Id;
 
-         --    Refined_State   => (State_1 => (C1, C2))
-         --    Depends         => (<output> => State)
-         --    Refined_Depends => (<output> => C1)
-         --  or
-         --    Refined_Depends => (<output> => (C1, C2))
+         begin
+            --  Normalization is performed only when the original clause has
+            --  more than one input. Multiple inputs appear as an aggregate.
 
-         if Nkind (Dep_Inputs) = N_Aggregate then
-            Dep_Input := First (Expressions (Dep_Inputs));
-            while Present (Dep_Input) loop
-               if not Input_Match
-                        (Dep_Input   => Dep_Input,
-                         Ref_Inputs  => Ref_Inputs,
-                         Post_Errors => Post_Errors)
-               then
-                  Result := False;
-               end if;
+            if Nkind (Inputs) = N_Aggregate then
+               Last_Input := Last (Expressions (Inputs));
 
-               Next (Dep_Input);
-            end loop;
+               --  Create a new clause for each input
 
-            Result := True;
+               Input := First (Expressions (Inputs));
+               while Present (Input) loop
+                  Next_Input := Next (Input);
 
-         --  Solitary input
+                  --  Unhook the current input from the original input list
+                  --  because it will be relocated to a new clause.
 
-         else
-            Result :=
-              Input_Match
-                (Dep_Input   => Dep_Inputs,
-                 Ref_Inputs  => Ref_Inputs,
-                 Post_Errors => Post_Errors);
-         end if;
+                  Remove (Input);
 
-         --  List all inputs that appear as extras
+                  --  Special processing for the last input. At this point the
+                  --  original aggregate has been stripped down to one element.
+                  --  Replace the aggregate by the element itself.
 
-         Report_Extra_Inputs;
+                  if Input = Last_Input then
+                     Rewrite (Inputs, Input);
 
-         return Result;
-      end Inputs_Match;
+                  --  Generate a clause of the form:
+                  --    Output => Input
 
-      -------------------------
-      -- Is_Self_Referential --
-      -------------------------
+                  else
+                     New_Clause :=
+                       Make_Component_Association (Loc,
+                         Choices    => New_Copy_List_Tree (Output),
+                         Expression => Input);
 
-      function Is_Self_Referential (Item_Id : Entity_Id) return Boolean is
-         function Denotes_Item (N : Node_Id) return Boolean;
-         --  Determine whether an arbitrary node N denotes item Item_Id
+                     --  The new clause contains replicated content that has
+                     --  already been analyzed, mark the clause as analyzed.
 
-         ------------------
-         -- Denotes_Item --
-         ------------------
+                     Set_Analyzed (New_Clause);
+                     Insert_After (Clause, New_Clause);
+                  end if;
 
-         function Denotes_Item (N : Node_Id) return Boolean is
-         begin
-            return
-              Is_Entity_Name (N)
-                and then Present (Entity (N))
-                and then Entity (N) = Item_Id;
-         end Denotes_Item;
+                  Input := Next_Input;
+               end loop;
+            end if;
+         end Normalize_Inputs;
 
          --  Local variables
 
-         Clauses : constant Node_Id :=
-                     Get_Pragma_Arg
-                       (First (Pragma_Argument_Associations (Depends)));
-         Clause  : Node_Id;
-         Input   : Node_Id;
-         Output  : Node_Id;
+         Clause : Node_Id;
 
-      --  Start of processing for Is_Self_Referential
+      --  Start of processing for Normalize_Clauses
 
       begin
-         Clause := First (Component_Associations (Clauses));
+         Clause := First (Clauses);
          while Present (Clause) loop
-
-            --  Due to normalization, a dependence clause has exactly one
-            --  output even if the original clause had multiple outputs.
-
-            Output := First (Choices (Clause));
-
-            --  Detect the following scenario:
-            --
-            --    Item_Id => [(...,] Item_Id [, ...)]
-
-            if Denotes_Item (Output) then
-               Input := Expression (Clause);
-
-               --  Multiple inputs appear as an aggregate
-
-               if Nkind (Input) = N_Aggregate then
-                  Input := First (Expressions (Input));
-
-                  if Denotes_Item (Input) then
-                     return True;
-                  end if;
-
-                  Next (Input);
-
-               --  Solitary input
-
-               elsif Denotes_Item (Input) then
-                  return True;
-               end if;
-            end if;
-
+            Normalize_Inputs (Clause);
             Next (Clause);
          end loop;
-
-         return False;
-      end Is_Self_Referential;
+      end Normalize_Clauses;
 
       --------------------------
       -- Report_Extra_Clauses --
@@ -22607,24 +22302,29 @@ package body Sem_Prag is
       if Nkind (Deps) = N_Null then
          SPARK_Msg_NE
            ("useless refinement, subprogram & does not depend on abstract "
-            & "state with visible refinement",
-            N, Spec_Id);
+            & "state with visible refinement", N, Spec_Id);
          return;
       end if;
 
-      --  Multiple dependency clauses appear as component associations of an
-      --  aggregate.
-
-      pragma Assert (Nkind (Deps) = N_Aggregate);
-      Dependencies := Component_Associations (Deps);
-
       --  Analyze Refined_Depends as if it behaved as a regular pragma Depends.
       --  This ensures that the categorization of all refined dependency items
       --  is consistent with their role.
 
       Analyze_Depends_In_Decl_Part (N);
 
+      --  Do not match dependencies against refinements if Refined_Depends is
+      --  illegal to avoid emitting misleading error.
+
       if Serious_Errors_Detected = Errors then
+
+         --  Multiple dependency clauses appear as component associations of an
+         --  aggregate. Note that the clauses are copied because the algorithm
+         --  modifies them and this should not be visible in Depends.
+
+         pragma Assert (Nkind (Deps) = N_Aggregate);
+         Dependencies := New_Copy_List_Tree (Component_Associations (Deps));
+         Normalize_Clauses (Dependencies);
+
          if Nkind (Refs) = N_Null then
             Refinements := No_List;
 
@@ -22633,33 +22333,24 @@ package body Sem_Prag is
          --  modifies them and this should not be visible in Refined_Depends.
 
          else pragma Assert (Nkind (Refs) = N_Aggregate);
-            Refinements := New_Copy_List (Component_Associations (Refs));
+            Refinements := New_Copy_List_Tree (Component_Associations (Refs));
+            Normalize_Clauses (Refinements);
          end if;
 
-         --  Inspect all the clauses of pragma Depends looking for a matching
-         --  clause in pragma Refined_Depends. The approach is to use the
-         --  sole output of a clause as a key. Output items are unique in a
-         --  dependence relation. Clause normalization also ensured that all
-         --  clauses have exactly one output. Depending on what the key is, one
-         --  or more refinement clauses may satisfy the dependency clause. Each
-         --  time a dependency clause is matched, its related refinement clause
-         --  is consumed. In the end, two things may happen:
-
-         --    1) A clause of pragma Depends was not matched in which case
-         --       Check_Dependency_Clause reports the error.
-
-         --    2) Refined_Depends has an extra clause in which case the error
-         --       is reported by Report_Extra_Clauses.
+         --  At this point the clauses of pragmas Depends and Refined_Depends
+         --  have been normalized into simple dependencies between one output
+         --  and one input. Examine all clauses of pragma Depends looking for
+         --  matching clauses in pragma Refined_Depends.
 
          Clause := First (Dependencies);
          while Present (Clause) loop
             Check_Dependency_Clause (Clause);
             Next (Clause);
          end loop;
-      end if;
 
-      if Serious_Errors_Detected = Errors then
-         Report_Extra_Clauses;
+         if Serious_Errors_Detected = Errors then
+            Report_Extra_Clauses;
+         end if;
       end if;
    end Analyze_Refined_Depends_In_Decl_Part;