------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ C A S E                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1996-2022, 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- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Atree;          use Atree;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Elists;         use Elists;
with Errout;         use Errout;
with Namet;          use Namet;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Opt;            use Opt;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Eval;       use Sem_Eval;
with Sem_Res;        use Sem_Res;
with Sem_Util;       use Sem_Util;
with Sem_Type;       use Sem_Type;
with Snames;         use Snames;
with Stand;          use Stand;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Stringt;        use Stringt;
with Table;
with Tbuild;         use Tbuild;
with Uintp;          use Uintp;

with Ada.Unchecked_Deallocation;

with GNAT.Heap_Sort_G;
with GNAT.Sets;

package body Sem_Case is

   type Choice_Bounds is record
     Lo   : Node_Id;
     Hi   : Node_Id;
     Node : Node_Id;
   end record;
   --  Represent one choice bounds entry with Lo and Hi values, Node points
   --  to the choice node itself.

   type Choice_Table_Type is array (Nat range <>) of Choice_Bounds;
   --  Table type used to sort the choices present in a case statement or
   --  record variant. The actual entries are stored in 1 .. Last, but we
   --  have a 0 entry for use in sorting.

   -----------------------
   -- Local Subprograms --
   -----------------------

   procedure Check_Choice_Set
     (Choice_Table   : in out Choice_Table_Type;
      Bounds_Type    : Entity_Id;
      Subtyp         : Entity_Id;
      Others_Present : Boolean;
      Case_Node      : Node_Id);
   --  This is the procedure which verifies that a set of case alternatives
   --  or record variant choices has no duplicates, and covers the range
   --  specified by Bounds_Type. Choice_Table contains the discrete choices
   --  to check. These must start at position 1.
   --
   --  Furthermore Choice_Table (0) must exist. This element is used by
   --  the sorting algorithm as a temporary. Others_Present is a flag
   --  indicating whether or not an Others choice is present. Finally
   --  Msg_Sloc gives the source location of the construct containing the
   --  choices in the Choice_Table.
   --
   --  Bounds_Type is the type whose range must be covered by the alternatives
   --
   --  Subtyp is the subtype of the expression. If its bounds are nonstatic
   --  the alternatives must cover its base type.

   function Choice_Image (Value : Uint; Ctype : Entity_Id) return Name_Id;
   --  Given a Pos value of enumeration type Ctype, returns the name
   --  ID of an appropriate string to be used in error message output.

   function Has_Static_Discriminant_Constraint
     (Subtyp : Entity_Id) return Boolean;
   --  Returns True if the given subtype is subject to a discriminant
   --  constraint and at least one of the constraint values is nonstatic.

   package Composite_Case_Ops is

      Simplified_Composite_Coverage_Rules : constant Boolean := True;
      --  Indicates that, as a temporary stopgap, we implement
      --  simpler coverage-checking rules when casing on a
      --  composite selector:
      --     1) Require that an Others choice must be given, regardless
      --        of whether all possible values are covered explicitly.
      --     2) No legality checks regarding overlapping choices.

      function Box_Value_Required (Subtyp : Entity_Id) return Boolean;
      --  If result is True, then the only allowed value (in a choice
      --  aggregate) for a component of this (sub)type is a box. This rule
      --  means that such a component can be ignored in case alternative
      --  selection. This in turn implies that it is ok if the component
      --  type doesn't meet the usual restrictions, such as not being an
      --  access/task/protected type, since nobody is going to look
      --  at it.

      function Choice_Count (Alternatives : List_Id) return Nat;
      --  The sum of the number of choices for each alternative in the given
      --  list.

      function Normalized_Case_Expr_Type
        (Case_Statement : Node_Id) return Entity_Id;
      --  Usually returns the Etype of the selector expression of the
      --  case statement. However, in the case of a constrained composite
      --  subtype with a nonstatic constraint, returns the unconstrained
      --  base type.

      function Scalar_Part_Count (Subtyp : Entity_Id) return Nat;
      --  Given the composite type Subtyp of a case selector, returns the
      --  number of scalar parts in an object of this type. This is the
      --  dimensionality of the associated Cartesian product space.

      package Array_Case_Ops is
         function Array_Choice_Length (Choice : Node_Id) return Nat;
         --  Given a choice expression of an array type, returns its length.

         function Unconstrained_Array_Effective_Length
           (Array_Type : Entity_Id; Case_Statement : Node_Id) return Nat;
         --  If the nominal subtype of the case selector is unconstrained,
         --  then use the length of the longest choice of the case statement.
         --  Components beyond that index value will not influence the case
         --  selection decision.

         function Unconstrained_Array_Scalar_Part_Count
           (Array_Type : Entity_Id; Case_Statement : Node_Id) return Nat;
         --  Same as Scalar_Part_Count except that the value used for the
         --  "length" of the array subtype being cased on is determined by
         --  calling Unconstrained_Array_Effective_Length.
      end Array_Case_Ops;

      generic
         Case_Statement : Node_Id;
      package Choice_Analysis is

         use Array_Case_Ops;

         type Alternative_Id is
           new Int range 1 .. List_Length (Alternatives (Case_Statement));
         type Choice_Id is
           new Int range 1 .. Choice_Count (Alternatives (Case_Statement));

         Case_Expr_Type : constant Entity_Id :=
           Normalized_Case_Expr_Type (Case_Statement);

         Unconstrained_Array_Case : constant Boolean :=
           Is_Array_Type (Case_Expr_Type)
             and then not Is_Constrained (Case_Expr_Type);

         --  If Unconstrained_Array_Case is True, choice lengths may differ:
         --    when "Aaa" | "Bb" | "C" | "" =>
         --
         --  Strictly speaking, the name "Unconstrained_Array_Case" is
         --  slightly imprecise; a subtype with a nonstatic constraint is
         --  also treated as unconstrained (see Normalize_Case_Expr_Type).

         type Part_Id is new Int range
           1 .. (if Unconstrained_Array_Case
                 then Unconstrained_Array_Scalar_Part_Count
                        (Case_Expr_Type, Case_Statement)
                 else Scalar_Part_Count (Case_Expr_Type));

         type Discrete_Range_Info is
           record
              Low, High : Uint;
           end record;

         type Composite_Range_Info is array (Part_Id) of Discrete_Range_Info;

         type Choice_Range_Info (Is_Others : Boolean := False) is
           record
              case Is_Others is
                 when False =>
                    Ranges : Composite_Range_Info;
                 when True =>
                    null;
              end case;
           end record;

         type Choices_Range_Info is array (Choice_Id) of Choice_Range_Info;

         package Value_Sets is

            type Value_Set is private;
            --  A set of points in the Cartesian product space defined
            --  by the composite type of the case selector.
            --  Implemented as an access type.

            type Set_Comparison is
              (Disjoint, Equal, Contains, Contained_By, Overlaps);

            function Compare (S1, S2 : Value_Set) return Set_Comparison;
            --  If either argument (or both) is empty, result is Disjoint.
            --  Otherwise, result is Equal if the two sets are equal.

            Empty : constant Value_Set;

            function Matching_Values
              (Info : Composite_Range_Info) return Value_Set;
            --  The Cartesian product of the given array of ranges
            --  (excluding any values outside the Cartesian product of the
            --  component ranges).

            procedure Union (Target : in out Value_Set; Source : Value_Set);
            --  Add elements of Source into Target

            procedure Remove (Target : in out Value_Set; Source : Value_Set);
            --  Remove elements of Source from Target

            function Complement_Is_Empty (Set : Value_Set) return Boolean;
            --  Return True iff the set is "maximal", in the sense that it
            --  includes every value in the Cartesian product of the
            --  component ranges.

            procedure Free_Value_Sets;
            --  Reclaim storage associated with implementation of this package.

         private
            type Value_Set is new Natural;
            --  An index for a table that will be declared in the package body.

            Empty : constant Value_Set := 0;

         end Value_Sets;

         type Single_Choice_Info (Is_Others : Boolean := False) is
           record
              Alternative : Alternative_Id;
              case Is_Others is
                 when False =>
                    Matches : Value_Sets.Value_Set;
                 when True =>
                    null;
              end case;
           end record;

         type Choices_Info is array (Choice_Id) of Single_Choice_Info;

         function Analysis return Choices_Info;
         --  Parse the case choices in order to determine the set of
         --  matching values associated with each choice.

         type Bound_Values is array (Positive range <>) of Node_Id;

      end Choice_Analysis;
   end Composite_Case_Ops;

   procedure Expand_Others_Choice
     (Case_Table    : Choice_Table_Type;
      Others_Choice : Node_Id;
      Choice_Type   : Entity_Id);
   --  The case table is the table generated by a call to Check_Choices
   --  (with just 1 .. Last_Choice entries present). Others_Choice is a
   --  pointer to the N_Others_Choice node (this routine is only called if
   --  an others choice is present), and Choice_Type is the discrete type
   --  of the bounds. The effect of this call is to analyze the cases and
   --  determine the set of values covered by others. This choice list is
   --  set in the Others_Discrete_Choices field of the N_Others_Choice node.

   ----------------------
   -- Check_Choice_Set --
   ----------------------

   procedure Check_Choice_Set
     (Choice_Table   : in out Choice_Table_Type;
      Bounds_Type    : Entity_Id;
      Subtyp         : Entity_Id;
      Others_Present : Boolean;
      Case_Node      : Node_Id)
   is
      Predicate_Error : Boolean := False;
      --  Flag to prevent cascaded errors when a static predicate is known to
      --  be violated by one choice.

      Num_Choices : constant Nat := Choice_Table'Last;

      procedure Check_Against_Predicate
        (Pred    : in out Node_Id;
         Choice  : Choice_Bounds;
         Prev_Lo : in out Uint;
         Prev_Hi : in out Uint;
         Error   : in out Boolean);
      --  Determine whether a choice covers legal values as defined by a static
      --  predicate set. Pred is a static predicate range. Choice is the choice
      --  to be examined. Prev_Lo and Prev_Hi are the bounds of the previous
      --  choice that covered a predicate set. Error denotes whether the check
      --  found an illegal intersection.

      procedure Check_Duplicates;
      --  Check for duplicate choices, and call Dup_Choice if there are any
      --  such errors. Note that predicates are irrelevant here.

      procedure Dup_Choice (Lo, Hi : Uint; C : Node_Id);
      --  Post message "duplication of choice value(s) bla bla at xx". Message
      --  is posted at location C. Caller sets Error_Msg_Sloc for xx.

      procedure Explain_Non_Static_Bound;
      --  Called when we find a nonstatic bound, requiring the base type to
      --  be covered. Provides where possible a helpful explanation of why the
      --  bounds are nonstatic, since this is not always obvious.

      function Lt_Choice (C1, C2 : Natural) return Boolean;
      --  Comparison routine for comparing Choice_Table entries. Use the lower
      --  bound of each Choice as the key.

      procedure Missing_Choice (Value1 : Node_Id; Value2 : Node_Id);
      procedure Missing_Choice (Value1 : Node_Id; Value2 : Uint);
      procedure Missing_Choice (Value1 : Uint;    Value2 : Node_Id);
      procedure Missing_Choice (Value1 : Uint;    Value2 : Uint);
      --  Issue an error message indicating that there are missing choices,
      --  followed by the image of the missing choices themselves which lie
      --  between Value1 and Value2 inclusive.

      procedure Missing_Choices (Pred : Node_Id; Prev_Hi : Uint);
      --  Emit an error message for each non-covered static predicate set.
      --  Prev_Hi denotes the upper bound of the last choice covering a set.

      procedure Move_Choice (From : Natural; To : Natural);
      --  Move routine for sorting the Choice_Table

      package Sorting is new GNAT.Heap_Sort_G (Move_Choice, Lt_Choice);

      -----------------------------
      -- Check_Against_Predicate --
      -----------------------------

      procedure Check_Against_Predicate
        (Pred    : in out Node_Id;
         Choice  : Choice_Bounds;
         Prev_Lo : in out Uint;
         Prev_Hi : in out Uint;
         Error   : in out Boolean)
      is
         procedure Illegal_Range
           (Loc : Source_Ptr;
            Lo  : Uint;
            Hi  : Uint);
         --  Emit an error message regarding a choice that clashes with the
         --  legal static predicate sets. Loc is the location of the choice
         --  that introduced the illegal range. Lo .. Hi is the range.

         function Inside_Range
           (Lo  : Uint;
            Hi  : Uint;
            Val : Uint) return Boolean;
         --  Determine whether position Val within a discrete type is within
         --  the range Lo .. Hi inclusive.

         -------------------
         -- Illegal_Range --
         -------------------

         procedure Illegal_Range
           (Loc : Source_Ptr;
            Lo  : Uint;
            Hi  : Uint)
         is
         begin
            Error_Msg_Name_1 := Chars (Bounds_Type);

            --  Single value

            if Lo = Hi then
               if Is_Integer_Type (Bounds_Type) then
                  Error_Msg_Uint_1 := Lo;
                  Error_Msg ("static predicate on % excludes value ^!", Loc);
               else
                  Error_Msg_Name_2 := Choice_Image (Lo, Bounds_Type);
                  Error_Msg ("static predicate on % excludes value %!", Loc);
               end if;

            --  Range

            else
               if Is_Integer_Type (Bounds_Type) then
                  Error_Msg_Uint_1 := Lo;
                  Error_Msg_Uint_2 := Hi;
                  Error_Msg
                    ("static predicate on % excludes range ^ .. ^!", Loc);
               else
                  Error_Msg_Name_2 := Choice_Image (Lo, Bounds_Type);
                  Error_Msg_Name_3 := Choice_Image (Hi, Bounds_Type);
                  Error_Msg
                    ("static predicate on % excludes range % .. %!", Loc);
               end if;
            end if;
         end Illegal_Range;

         ------------------
         -- Inside_Range --
         ------------------

         function Inside_Range
           (Lo  : Uint;
            Hi  : Uint;
            Val : Uint) return Boolean
         is
         begin
            return Lo <= Val and then Val <= Hi;
         end Inside_Range;

         --  Local variables

         Choice_Hi : constant Uint := Expr_Value (Choice.Hi);
         Choice_Lo : constant Uint := Expr_Value (Choice.Lo);
         Loc       : Source_Ptr;
         LocN      : Node_Id;
         Next_Hi   : Uint;
         Next_Lo   : Uint;
         Pred_Hi   : Uint;
         Pred_Lo   : Uint;

      --  Start of processing for Check_Against_Predicate

      begin
         --  Find the proper error message location

         if Present (Choice.Node) then
            LocN := Choice.Node;
         else
            LocN := Case_Node;
         end if;

         Loc := Sloc (LocN);

         if Present (Pred) then
            Pred_Lo := Expr_Value (Low_Bound  (Pred));
            Pred_Hi := Expr_Value (High_Bound (Pred));

         --  Previous choices managed to satisfy all static predicate sets

         else
            Illegal_Range (Loc, Choice_Lo, Choice_Hi);
            Error := True;
            return;
         end if;

         --  Step 1: Ignore duplicate choices, other than to set the flag,
         --  because these were already detected by Check_Duplicates.

         if Inside_Range (Choice_Lo, Choice_Hi, Prev_Lo)
           or else  Inside_Range (Choice_Lo, Choice_Hi, Prev_Hi)
         then
            Error := True;

         --  Step 2: Detect full coverage

         --  Choice_Lo    Choice_Hi
         --  +============+
         --  Pred_Lo      Pred_Hi

         elsif Choice_Lo = Pred_Lo and then Choice_Hi = Pred_Hi then
            Prev_Lo := Choice_Lo;
            Prev_Hi := Choice_Hi;
            Next (Pred);

         --  Step 3: Detect all cases where a choice mentions values that are
         --  not part of the static predicate sets.

         --  Choice_Lo   Choice_Hi   Pred_Lo   Pred_Hi
         --  +-----------+ . . . . . +=========+
         --   ^ illegal ^

         elsif Choice_Lo < Pred_Lo and then Choice_Hi < Pred_Lo then
            Illegal_Range (Loc, Choice_Lo, Choice_Hi);
            Error := True;

         --  Choice_Lo   Pred_Lo   Choice_Hi   Pred_Hi
         --  +-----------+=========+===========+
         --   ^ illegal ^

         elsif Choice_Lo < Pred_Lo
           and then Inside_Range (Pred_Lo, Pred_Hi, Choice_Hi)
         then
            Illegal_Range (Loc, Choice_Lo, Pred_Lo - 1);
            Error := True;

         --  Pred_Lo   Pred_Hi   Choice_Lo   Choice_Hi
         --  +=========+ . . . . +-----------+
         --                       ^ illegal ^

         elsif Pred_Lo < Choice_Lo and then Pred_Hi < Choice_Lo then
            if Others_Present then

               --  Current predicate set is covered by others clause.

               null;

            else
               Missing_Choice (Pred_Lo, Pred_Hi);
               Error := True;
            end if;

            --  There may be several static predicate sets between the current
            --  one and the choice. Inspect the next static predicate set.

            Next (Pred);
            Check_Against_Predicate
              (Pred    => Pred,
               Choice  => Choice,
               Prev_Lo => Prev_Lo,
               Prev_Hi => Prev_Hi,
               Error   => Error);

         --  Pred_Lo   Choice_Lo   Pred_Hi     Choice_Hi
         --  +=========+===========+-----------+
         --                         ^ illegal ^

         elsif Pred_Hi < Choice_Hi
           and then Inside_Range (Pred_Lo, Pred_Hi, Choice_Lo)
         then
            Next (Pred);

            --  The choice may fall in a static predicate set. If this is the
            --  case, avoid mentioning legal values in the error message.

            if Present (Pred) then
               Next_Lo := Expr_Value (Low_Bound  (Pred));
               Next_Hi := Expr_Value (High_Bound (Pred));

               --  The next static predicate set is to the right of the choice

               if Choice_Hi < Next_Lo and then Choice_Hi < Next_Hi then
                  Illegal_Range (Loc, Pred_Hi + 1, Choice_Hi);
               else
                  Illegal_Range (Loc, Pred_Hi + 1, Next_Lo - 1);
               end if;
            else
               Illegal_Range (Loc, Pred_Hi + 1, Choice_Hi);
            end if;

            Error := True;

         --  Choice_Lo   Pred_Lo   Pred_Hi     Choice_Hi
         --  +-----------+=========+-----------+
         --   ^ illegal ^           ^ illegal ^

         --  Emit an error on the low gap, disregard the upper gap

         elsif Choice_Lo < Pred_Lo and then Pred_Hi < Choice_Hi then
            Illegal_Range (Loc, Choice_Lo, Pred_Lo - 1);
            Error := True;

         --  Step 4: Detect all cases of partial or missing coverage

         --  Pred_Lo   Choice_Lo  Choice_Hi   Pred_Hi
         --  +=========+==========+===========+
         --   ^  gap  ^            ^   gap   ^

         else
            --  An "others" choice covers all gaps

            if Others_Present then
               Prev_Lo := Choice_Lo;
               Prev_Hi := Choice_Hi;

               --  Check whether predicate set is fully covered by choice

               if Pred_Hi = Choice_Hi then
                  Next (Pred);
               end if;

            --  Choice_Lo   Choice_Hi   Pred_Hi
            --  +===========+===========+
            --  Pred_Lo      ^   gap   ^

            --  The upper gap may be covered by a subsequent choice

            elsif Pred_Lo = Choice_Lo then
               Prev_Lo := Choice_Lo;
               Prev_Hi := Choice_Hi;

            --  Pred_Lo     Prev_Hi   Choice_Lo   Choice_Hi   Pred_Hi
            --  +===========+=========+===========+===========+
            --   ^ covered ^ ^  gap  ^

            else pragma Assert (Pred_Lo < Choice_Lo);

               --  A previous choice covered the gap up to the current choice

               if Prev_Hi = Choice_Lo - 1 then
                  Prev_Lo := Choice_Lo;
                  Prev_Hi := Choice_Hi;

                  if Choice_Hi = Pred_Hi then
                     Next (Pred);
                  end if;

               --  The previous choice did not intersect with the current
               --  static predicate set.

               elsif Prev_Hi < Pred_Lo then
                  Missing_Choice (Pred_Lo, Choice_Lo - 1);
                  Error := True;

               --  The previous choice covered part of the static predicate set
               --  but there is a gap after Prev_Hi.

               else
                  Missing_Choice (Prev_Hi + 1, Choice_Lo - 1);
                  Error := True;
               end if;
            end if;
         end if;
      end Check_Against_Predicate;

      ----------------------
      -- Check_Duplicates --
      ----------------------

      procedure Check_Duplicates is
         Choice      : Node_Id;
         Choice_Hi   : Uint;
         Choice_Lo   : Uint;
         Prev_Choice : Node_Id := Empty;
         Prev_Hi     : Uint;

      begin
         Prev_Hi := Expr_Value (Choice_Table (1).Hi);

         for Outer_Index in 2 .. Num_Choices loop
            Choice_Lo := Expr_Value (Choice_Table (Outer_Index).Lo);
            Choice_Hi := Expr_Value (Choice_Table (Outer_Index).Hi);

            --  Choices overlap; this is an error

            if Choice_Lo <= Prev_Hi then
               Choice := Choice_Table (Outer_Index).Node;

               --  Find first previous choice that overlaps

               for Inner_Index in 1 .. Outer_Index - 1 loop
                  if Choice_Lo <=
                       Expr_Value (Choice_Table (Inner_Index).Hi)
                  then
                     Prev_Choice := Choice_Table (Inner_Index).Node;
                     exit;
                  end if;
               end loop;

               pragma Assert (Present (Prev_Choice));

               if Sloc (Prev_Choice) <= Sloc (Choice) then
                  Error_Msg_Sloc := Sloc (Prev_Choice);
                  Dup_Choice (Choice_Lo, UI_Min (Choice_Hi, Prev_Hi), Choice);
               else
                  Error_Msg_Sloc := Sloc (Choice);
                  Dup_Choice
                    (Choice_Lo, UI_Min (Choice_Hi, Prev_Hi), Prev_Choice);
               end if;
            end if;

            if Choice_Hi > Prev_Hi then
               Prev_Hi := Choice_Hi;
            end if;
         end loop;
      end Check_Duplicates;

      ----------------
      -- Dup_Choice --
      ----------------

      procedure Dup_Choice (Lo, Hi : Uint; C : Node_Id) is
      begin
         --  In some situations, we call this with a null range, and obviously
         --  we don't want to complain in this case.

         if Lo > Hi then
            return;
         end if;

         --  Case of only one value that is duplicated

         if Lo = Hi then

            --  Integer type

            if Is_Integer_Type (Bounds_Type) then

               --  We have an integer value, Lo, but if the given choice
               --  placement is a constant with that value, then use the
               --  name of that constant instead in the message:

               if Nkind (C) = N_Identifier
                 and then Compile_Time_Known_Value (C)
                 and then Expr_Value (C) = Lo
               then
                  Error_Msg_N
                    ("duplication of choice value: &#!", Original_Node (C));

               --  Not that special case, so just output the integer value

               else
                  Error_Msg_Uint_1 := Lo;
                  Error_Msg_N
                    ("duplication of choice value: ^#!", Original_Node (C));
               end if;

            --  Enumeration type

            else
               Error_Msg_Name_1 := Choice_Image (Lo, Bounds_Type);
               Error_Msg_N
                 ("duplication of choice value: %#!", Original_Node (C));
            end if;

         --  More than one choice value, so print range of values

         else
            --  Integer type

            if Is_Integer_Type (Bounds_Type) then

               --  Similar to the above, if C is a range of known values which
               --  match Lo and Hi, then use the names. We have to go to the
               --  original nodes, since the values will have been rewritten
               --  to their integer values.

               if Nkind (C) = N_Range
                 and then Nkind (Original_Node (Low_Bound  (C))) = N_Identifier
                 and then Nkind (Original_Node (High_Bound (C))) = N_Identifier
                 and then Compile_Time_Known_Value (Low_Bound (C))
                 and then Compile_Time_Known_Value (High_Bound (C))
                 and then Expr_Value (Low_Bound (C))  = Lo
                 and then Expr_Value (High_Bound (C)) = Hi
               then
                  Error_Msg_Node_2 := Original_Node (High_Bound (C));
                  Error_Msg_N
                    ("duplication of choice values: & .. &#!",
                     Original_Node (Low_Bound (C)));

               --  Not that special case, output integer values

               else
                  Error_Msg_Uint_1 := Lo;
                  Error_Msg_Uint_2 := Hi;
                  Error_Msg_N
                    ("duplication of choice values: ^ .. ^#!",
                     Original_Node (C));
               end if;

            --  Enumeration type

            else
               Error_Msg_Name_1 := Choice_Image (Lo, Bounds_Type);
               Error_Msg_Name_2 := Choice_Image (Hi, Bounds_Type);
               Error_Msg_N
                 ("duplication of choice values: % .. %#!", Original_Node (C));
            end if;
         end if;
      end Dup_Choice;

      ------------------------------
      -- Explain_Non_Static_Bound --
      ------------------------------

      procedure Explain_Non_Static_Bound is
         Expr : Node_Id;

      begin
         if Nkind (Case_Node) = N_Variant_Part then
            Expr := Name (Case_Node);
         else
            Expr := Expression (Case_Node);
         end if;

         if Bounds_Type /= Subtyp then

            --  If the case is a variant part, the expression is given by the
            --  discriminant itself, and the bounds are the culprits.

            if Nkind (Case_Node) = N_Variant_Part then
               Error_Msg_NE
                 ("bounds of & are not static, "
                  & "alternatives must cover base type!", Expr, Expr);

            --  If this is a case statement, the expression may be nonstatic
            --  or else the subtype may be at fault.

            elsif Is_Entity_Name (Expr) then
               Error_Msg_NE
                 ("bounds of & are not static, "
                  & "alternatives must cover base type!", Expr, Expr);

            else
               Error_Msg_N
                 ("subtype of expression is not static, "
                  & "alternatives must cover base type!", Expr);
            end if;

         --  Otherwise the expression is not static, even if the bounds of the
         --  type are, or else there are missing alternatives. If both, the
         --  additional information may be redundant but harmless. Examine
         --  whether original node is an entity, because it may have been
         --  constant-folded to a literal if value is known.

         elsif not Is_Entity_Name (Original_Node (Expr)) then
            Error_Msg_N
              ("subtype of expression is not static, "
               & "alternatives must cover base type!", Expr);
         end if;
      end Explain_Non_Static_Bound;

      ---------------
      -- Lt_Choice --
      ---------------

      function Lt_Choice (C1, C2 : Natural) return Boolean is
      begin
         return
           Expr_Value (Choice_Table (Nat (C1)).Lo)
             <
           Expr_Value (Choice_Table (Nat (C2)).Lo);
      end Lt_Choice;

      --------------------
      -- Missing_Choice --
      --------------------

      procedure Missing_Choice (Value1 : Node_Id; Value2 : Node_Id) is
      begin
         Missing_Choice (Expr_Value (Value1), Expr_Value (Value2));
      end Missing_Choice;

      procedure Missing_Choice (Value1 : Node_Id; Value2 : Uint) is
      begin
         Missing_Choice (Expr_Value (Value1), Value2);
      end Missing_Choice;

      procedure Missing_Choice (Value1 : Uint; Value2 : Node_Id) is
      begin
         Missing_Choice (Value1, Expr_Value (Value2));
      end Missing_Choice;

      --------------------
      -- Missing_Choice --
      --------------------

      procedure Missing_Choice (Value1 : Uint; Value2 : Uint) is
      begin
         --  AI05-0188 : within an instance the non-others choices do not have
         --  to belong to the actual subtype.

         if Ada_Version >= Ada_2012 and then In_Instance then
            return;

         --  In some situations, we call this with a null range, and obviously
         --  we don't want to complain in this case.

         elsif Value1 > Value2 then
            return;

         --  If predicate is already known to be violated, do not check for
         --  coverage error, to prevent cascaded messages.

         elsif Predicate_Error then
            return;
         end if;

         --  Case of only one value that is missing

         if Value1 = Value2 then
            if Is_Integer_Type (Bounds_Type) then
               Error_Msg_Uint_1 := Value1;
               Error_Msg_N ("missing case value: ^!", Case_Node);
            else
               Error_Msg_Name_1 := Choice_Image (Value1, Bounds_Type);
               Error_Msg_N ("missing case value: %!", Case_Node);
            end if;

         --  More than one choice value, so print range of values

         else
            if Is_Integer_Type (Bounds_Type) then
               Error_Msg_Uint_1 := Value1;
               Error_Msg_Uint_2 := Value2;
               Error_Msg_N ("missing case values: ^ .. ^!", Case_Node);
            else
               Error_Msg_Name_1 := Choice_Image (Value1, Bounds_Type);
               Error_Msg_Name_2 := Choice_Image (Value2, Bounds_Type);
               Error_Msg_N ("missing case values: % .. %!", Case_Node);
            end if;
         end if;
      end Missing_Choice;

      ---------------------
      -- Missing_Choices --
      ---------------------

      procedure Missing_Choices (Pred : Node_Id; Prev_Hi : Uint) is
         Hi  : Uint;
         Lo  : Uint;
         Set : Node_Id;

      begin
         Set := Pred;
         while Present (Set) loop
            Lo := Expr_Value (Low_Bound (Set));
            Hi := Expr_Value (High_Bound (Set));

            --  A choice covered part of a static predicate set

            if Lo <= Prev_Hi and then Prev_Hi < Hi then
               Missing_Choice (Prev_Hi + 1, Hi);

            else
               Missing_Choice (Lo, Hi);
            end if;

            Next (Set);
         end loop;
      end Missing_Choices;

      -----------------
      -- Move_Choice --
      -----------------

      procedure Move_Choice (From : Natural; To : Natural) is
      begin
         Choice_Table (Nat (To)) := Choice_Table (Nat (From));
      end Move_Choice;

      --  Local variables

      Bounds_Hi     : constant Node_Id := Type_High_Bound (Bounds_Type);
      Bounds_Lo     : constant Node_Id := Type_Low_Bound  (Bounds_Type);
      Has_Predicate : constant Boolean :=
                        Is_OK_Static_Subtype (Bounds_Type)
                          and then Has_Static_Predicate (Bounds_Type);

      Choice_Hi   : Uint;
      Choice_Lo   : Uint;
      Pred        : Node_Id;
      Prev_Lo     : Uint;
      Prev_Hi     : Uint;

   --  Start of processing for Check_Choice_Set

   begin
      --  If the case is part of a predicate aspect specification, do not
      --  recheck it against itself.

      if Present (Parent (Case_Node))
        and then Nkind (Parent (Case_Node)) = N_Aspect_Specification
      then
         return;
      end if;

      --  Choice_Table must start at 0 which is an unused location used by the
      --  sorting algorithm. However the first valid position for a discrete
      --  choice is 1.

      pragma Assert (Choice_Table'First = 0);

      --  The choices do not cover the base range. Emit an error if "others" is
      --  not available and return as there is no need for further processing.

      if Num_Choices = 0 then
         if not Others_Present then
            Missing_Choice (Bounds_Lo, Bounds_Hi);
         end if;

         return;
      end if;

      Sorting.Sort (Positive (Choice_Table'Last));

      --  First check for duplicates. This involved the choices; predicates, if
      --  any, are irrelevant.

      Check_Duplicates;

      --  Then check for overlaps

      --  If the subtype has a static predicate, the predicate defines subsets
      --  of legal values and requires finer-grained analysis.

      --  Note that in GNAT the predicate is considered static if the predicate
      --  expression is static, independently of whether the aspect mentions
      --  Static explicitly.

      if Has_Predicate then
         Pred := First (Static_Discrete_Predicate (Bounds_Type));

         --  Make initial value smaller than 'First of type, so that first
         --  range comparison succeeds. This applies both to integer types
         --  and to enumeration types.

         Prev_Lo := Expr_Value (Type_Low_Bound (Bounds_Type)) - 1;
         Prev_Hi := Prev_Lo;

         declare
            Error : Boolean := False;
         begin
            for Index in 1 .. Num_Choices loop
               Check_Against_Predicate
                 (Pred    => Pred,
                  Choice  => Choice_Table (Index),
                  Prev_Lo => Prev_Lo,
                  Prev_Hi => Prev_Hi,
                  Error   => Error);

               --  The analysis detected an illegal intersection between a
               --  choice and a static predicate set. Do not examine other
               --  choices unless all errors are requested.

               if Error then
                  Predicate_Error := True;

                  if not All_Errors_Mode then
                     return;
                  end if;
               end if;
            end loop;
         end;

         if Predicate_Error then
            return;
         end if;

         --  The choices may legally cover some of the static predicate sets,
         --  but not all. Emit an error for each non-covered set.

         if not Others_Present then
            Missing_Choices (Pred, Prev_Hi);
         end if;

      --  Default analysis

      else
         Choice_Lo := Expr_Value (Choice_Table (1).Lo);
         Choice_Hi := Expr_Value (Choice_Table (1).Hi);
         Prev_Hi   := Choice_Hi;

         if not Others_Present and then Expr_Value (Bounds_Lo) < Choice_Lo then
            Missing_Choice (Bounds_Lo, Choice_Lo - 1);

            --  If values are missing outside of the subtype, add explanation.
            --  No additional message if only one value is missing.

            if Expr_Value (Bounds_Lo) < Choice_Lo - 1 then
               Explain_Non_Static_Bound;
            end if;
         end if;

         for Index in 2 .. Num_Choices loop
            Choice_Lo := Expr_Value (Choice_Table (Index).Lo);
            Choice_Hi := Expr_Value (Choice_Table (Index).Hi);

            if Choice_Lo > Prev_Hi + 1 and then not Others_Present then
               Missing_Choice (Prev_Hi + 1, Choice_Lo - 1);
            end if;

            if Choice_Hi > Prev_Hi then
               Prev_Hi := Choice_Hi;
            end if;
         end loop;

         if not Others_Present and then Expr_Value (Bounds_Hi) > Prev_Hi then
            Missing_Choice (Prev_Hi + 1, Bounds_Hi);

            if Expr_Value (Bounds_Hi) > Prev_Hi + 1 then
               Explain_Non_Static_Bound;
            end if;
         end if;
      end if;
   end Check_Choice_Set;

   ------------------
   -- Choice_Image --
   ------------------

   function Choice_Image (Value : Uint; Ctype : Entity_Id) return Name_Id is
      Rtp : constant Entity_Id := Root_Type (Ctype);
      Lit : Entity_Id;
      C   : Int;

   begin
      --  For character, or wide [wide] character. If 7-bit ASCII graphic
      --  range, then build and return appropriate character literal name

      if Is_Standard_Character_Type (Ctype) then
         C := UI_To_Int (Value);

         if C in 16#20# .. 16#7E# then
            Set_Character_Literal_Name (UI_To_CC (Value));
            return Name_Find;
         end if;

      --  For user defined enumeration type, find enum/char literal

      else
         Lit := First_Literal (Rtp);

         for J in 1 .. UI_To_Int (Value) loop
            Next_Literal (Lit);
         end loop;

         --  If enumeration literal, just return its value

         if Nkind (Lit) = N_Defining_Identifier then
            return Chars (Lit);

         --  For character literal, get the name and use it if it is
         --  for a 7-bit ASCII graphic character in 16#20#..16#7E#.

         else
            Get_Decoded_Name_String (Chars (Lit));

            if Name_Len = 3
              and then Name_Buffer (2) in
                Character'Val (16#20#) .. Character'Val (16#7E#)
            then
               return Chars (Lit);
            end if;
         end if;
      end if;

      --  If we fall through, we have a character literal which is not in
      --  the 7-bit ASCII graphic set. For such cases, we construct the
      --  name "type'val(nnn)" where type is the choice type, and nnn is
      --  the pos value passed as an argument to Choice_Image.

      Get_Name_String (Chars (First_Subtype (Ctype)));

      Add_Str_To_Name_Buffer ("'val(");
      UI_Image (Value);
      Add_Str_To_Name_Buffer (UI_Image_Buffer (1 .. UI_Image_Length));
      Add_Char_To_Name_Buffer (')');
      return Name_Find;
   end Choice_Image;

   package body Composite_Case_Ops is

      function Static_Array_Length (Subtyp : Entity_Id) return Nat;
      --  Given a one-dimensional constrained array subtype with
      --  statically known bounds, return its length.

      -------------------------
      -- Static_Array_Length --
      -------------------------

      function Static_Array_Length (Subtyp : Entity_Id) return Nat is
         pragma Assert (Is_Constrained (Subtyp));
         pragma Assert (Number_Dimensions (Subtyp) = 1);
         Index : constant Node_Id := First_Index (Subtyp);
         pragma Assert (Is_OK_Static_Range (Index));
         Lo  : constant Uint := Expr_Value (Low_Bound (Index));
         Hi  : constant Uint := Expr_Value (High_Bound (Index));
         Len : constant Uint := UI_Max (0, (Hi - Lo) + 1);
      begin
         return UI_To_Int (Len);
      end Static_Array_Length;

      ------------------------
      -- Box_Value_Required --
      ------------------------

      function Box_Value_Required (Subtyp : Entity_Id) return Boolean is
         --  Some of these restrictions will be relaxed eventually, but best
         --  to initially err in the direction of being too restrictive.
      begin
         if Has_Predicates (Subtyp) then
            return True;
         elsif Is_Discrete_Type (Subtyp) then
            if not Is_Static_Subtype (Subtyp) then
               return True;
            elsif Is_Enumeration_Type (Subtyp)
               and then Has_Enumeration_Rep_Clause (Subtyp)
               --  Maybe enumeration rep clauses can be ignored here?
            then
               return True;
            end if;
         elsif Is_Array_Type (Subtyp) then
            if Number_Dimensions (Subtyp) /= 1 then
               return True;
            elsif not Is_Constrained (Subtyp) then
               if not Is_Static_Subtype (Etype (First_Index (Subtyp))) then
                  return True;
               end if;
            elsif not Is_OK_Static_Range (First_Index (Subtyp)) then
               return True;
            end if;
         elsif Is_Record_Type (Subtyp) then
            if Has_Discriminants (Subtyp)
              and then Is_Constrained (Subtyp)
              and then not Has_Static_Discriminant_Constraint (Subtyp)
            then
               --  Perhaps treat differently the case where Subtyp is the
               --  subtype of the top-level selector expression, as opposed
               --  to the subtype of some subcomponent thereof.
               return True;
            end if;
         else
            --  Return True for any type that is not a discrete type,
            --  a record type, or an array type.
            return True;
         end if;

         return False;
      end Box_Value_Required;

      ------------------
      -- Choice_Count --
      ------------------

      function Choice_Count (Alternatives : List_Id) return Nat is
         Result : Nat := 0;
         Alt : Node_Id := First (Alternatives);
      begin
         while Present (Alt) loop
            Result := Result + List_Length (Discrete_Choices (Alt));
            Next (Alt);
         end loop;
         return Result;
      end Choice_Count;

      -------------------------------
      -- Normalized_Case_Expr_Type --
      -------------------------------

      function Normalized_Case_Expr_Type
        (Case_Statement : Node_Id) return Entity_Id
      is
         Unnormalized : constant Entity_Id :=
           Etype (Expression (Case_Statement));

         Is_Dynamically_Constrained_Array : constant Boolean :=
           Is_Array_Type (Unnormalized)
             and then Is_Constrained (Unnormalized)
             and then not Has_Static_Array_Bounds (Unnormalized);

         Is_Dynamically_Constrained_Record : constant Boolean :=
           Is_Record_Type (Unnormalized)
             and then Has_Discriminants (Unnormalized)
             and then Is_Constrained (Unnormalized)
             and then not Has_Static_Discriminant_Constraint (Unnormalized);
      begin
         if Is_Dynamically_Constrained_Array
           or Is_Dynamically_Constrained_Record
         then
            return Base_Type (Unnormalized);
         else
            return Unnormalized;
         end if;
      end Normalized_Case_Expr_Type;

      -----------------------
      -- Scalar_Part_Count --
      -----------------------

      function Scalar_Part_Count (Subtyp : Entity_Id) return Nat is
      begin
         if Box_Value_Required (Subtyp) then
            return 0; -- component does not participate in case selection
         elsif Is_Scalar_Type (Subtyp) then
            return 1;
         elsif Is_Array_Type (Subtyp) then
            return Static_Array_Length (Subtyp)
              * Scalar_Part_Count (Component_Type (Subtyp));
         elsif Is_Record_Type (Subtyp) then
            declare
               Result : Nat := 0;
               Comp : Entity_Id := First_Component_Or_Discriminant
                                     (Base_Type (Subtyp));
            begin
               while Present (Comp) loop
                  Result := Result + Scalar_Part_Count (Etype (Comp));
                  Next_Component_Or_Discriminant (Comp);
               end loop;
               return Result;
            end;
         else
            pragma Assert (Serious_Errors_Detected > 0);
            return 0;
         end if;
      end Scalar_Part_Count;

      package body Array_Case_Ops is

         -------------------------
         -- Array_Choice_Length --
         -------------------------

         function Array_Choice_Length (Choice : Node_Id) return Nat is
         begin
            case Nkind (Choice) is
               when N_String_Literal =>
                  return String_Length (Strval (Choice));
               when N_Aggregate =>
                  declare
                     Bounds : constant Node_Id :=
                       Aggregate_Bounds (Choice);
                     pragma Assert (Is_OK_Static_Range (Bounds));
                     Lo     : constant Uint :=
                       Expr_Value (Low_Bound (Bounds));
                     Hi     : constant Uint :=
                       Expr_Value (High_Bound (Bounds));
                     Len : constant Uint := (Hi - Lo) + 1;
                  begin
                     return UI_To_Int (Len);
                  end;
               when N_Has_Entity =>
                  if Present (Entity (Choice))
                    and then Ekind (Entity (Choice)) = E_Constant
                  then
                     return Array_Choice_Length
                              (Expression (Parent (Entity (Choice))));
                  end if;
               when N_Others_Choice =>
                  return 0;
               when others =>
                  null;
            end case;

            if Nkind (Original_Node (Choice))
                 in N_String_Literal | N_Aggregate
            then
               return Array_Choice_Length (Original_Node (Choice));
            end if;

            Error_Msg_N ("Unsupported case choice", Choice);
            return 0;
         end Array_Choice_Length;

         ------------------------------------------
         -- Unconstrained_Array_Effective_Length --
         ------------------------------------------

         function Unconstrained_Array_Effective_Length
           (Array_Type : Entity_Id; Case_Statement : Node_Id) return Nat
         is
            pragma Assert (Is_Array_Type (Array_Type));
            --  Array_Type is otherwise unreferenced for now.

            Result : Nat := 0;
            Alt : Node_Id := First (Alternatives (Case_Statement));
         begin
            while Present (Alt) loop
               declare
                  Choice : Node_Id := First (Discrete_Choices (Alt));
               begin
                  while Present (Choice) loop
                     Result := Nat'Max (Result, Array_Choice_Length (Choice));
                     Next (Choice);
                  end loop;
               end;
               Next (Alt);
            end loop;

            return Result;
         end Unconstrained_Array_Effective_Length;

         -------------------------------------------
         -- Unconstrained_Array_Scalar_Part_Count --
         -------------------------------------------

         function Unconstrained_Array_Scalar_Part_Count
           (Array_Type : Entity_Id; Case_Statement : Node_Id) return Nat
         is
         begin
            --  Add one for the length, which is treated like a discriminant

            return 1 + (Unconstrained_Array_Effective_Length
                          (Array_Type     => Array_Type,
                           Case_Statement => Case_Statement)
                        * Scalar_Part_Count (Component_Type (Array_Type)));
         end Unconstrained_Array_Scalar_Part_Count;

      end Array_Case_Ops;

      package body Choice_Analysis is

         function Component_Bounds_Info return Composite_Range_Info;
         --  Returns the (statically known) bounds for each component.
         --  The selector expression value (or any other value of the type
         --  of the selector expression) can be thought of as a point in the
         --  Cartesian product of these sets.

         function Parse_Choice (Choice : Node_Id;
                                Alt    : Node_Id) return Choice_Range_Info;
         --  Extract Choice_Range_Info from a Choice node

         ---------------------------
         -- Component_Bounds_Info --
         ---------------------------

         function Component_Bounds_Info return Composite_Range_Info is
            Result : Composite_Range_Info;
            Next   : Part_Id := 1;
            Done   : Boolean := False;

            procedure Update_Result (Info : Discrete_Range_Info);
            --  Initialize first remaining uninitialized element of Result.
            --  Also set Next and Done.

            -------------------
            -- Update_Result --
            -------------------

            procedure Update_Result (Info : Discrete_Range_Info) is
            begin
               Result (Next) := Info;
               if Next /= Part_Id'Last then
                  Next := Next + 1;
               else
                  pragma Assert (not Done);
                  Done := True;
               end if;
            end Update_Result;

            procedure Traverse_Discrete_Parts (Subtyp : Entity_Id);
            --  Traverse the given subtype, looking for discrete parts.
            --  For an array subtype of length N, the element subtype
            --  is traversed N times. For a record subtype, traverse
            --  each component's subtype (once). When a discrete part is
            --  found, call Update_Result.

            -----------------------------
            -- Traverse_Discrete_Parts --
            -----------------------------

            procedure Traverse_Discrete_Parts (Subtyp : Entity_Id) is
            begin
               if Box_Value_Required (Subtyp) then
                  return;
               end if;

               if Is_Discrete_Type (Subtyp) then
                  Update_Result
                    ((Low  => Expr_Value (Type_Low_Bound (Subtyp)),
                      High => Expr_Value (Type_High_Bound (Subtyp))));
               elsif Is_Array_Type (Subtyp) then
                  declare
                     Len : Nat;
                  begin
                     if Is_Constrained (Subtyp) then
                        Len := Static_Array_Length (Subtyp);
                     else
                        --  Length will be treated like a discriminant;
                        --  We could compute High more precisely as
                        --    1 + Index_Subtype'Last - Index_Subtype'First
                        --  (we currently require that those bounds be
                        --  static, so this is an option), but only downside of
                        --  overshooting is if somebody wants to omit a
                        --  "when others" choice and exhaustively cover all
                        --  possibilities explicitly.
                        Update_Result
                          ((Low  => Uint_0,
                            High => Uint_2 ** Uint_32));

                        Len := Unconstrained_Array_Effective_Length
                                 (Array_Type     => Subtyp,
                                  Case_Statement => Case_Statement);
                     end if;
                     for I in 1 .. Len loop
                        Traverse_Discrete_Parts (Component_Type (Subtyp));
                     end loop;
                  end;
               elsif Is_Record_Type (Subtyp) then
                  if Has_Static_Discriminant_Constraint (Subtyp) then

                     --  The component range for a constrained discriminant
                     --  is a single value.
                     declare
                        Dc_Elmt : Elmt_Id :=
                          First_Elmt (Discriminant_Constraint (Subtyp));
                        Dc_Value : Uint;
                     begin
                        while Present (Dc_Elmt) loop
                           Dc_Value := Expr_Value (Node (Dc_Elmt));
                           Update_Result ((Low  => Dc_Value,
                                           High => Dc_Value));

                           Next_Elmt (Dc_Elmt);
                        end loop;
                     end;

                     --  Generate ranges for nondiscriminant components.
                     declare
                        Comp : Entity_Id := First_Component
                                              (Base_Type (Subtyp));
                     begin
                        while Present (Comp) loop
                           Traverse_Discrete_Parts (Etype (Comp));
                           Next_Component (Comp);
                        end loop;
                     end;
                  else
                     --  Generate ranges for all components
                     declare
                        Comp : Entity_Id :=
                          First_Component_Or_Discriminant
                            (Base_Type (Subtyp));
                     begin
                        while Present (Comp) loop
                           Traverse_Discrete_Parts (Etype (Comp));
                           Next_Component_Or_Discriminant (Comp);
                        end loop;
                     end;
                  end if;
               else
                  Error_Msg_N
                    ("case selector type having a non-discrete non-record"
                     & "  non-array subcomponent type not implemented",
                     Expression (Case_Statement));
               end if;
            end Traverse_Discrete_Parts;

         begin
            Traverse_Discrete_Parts (Case_Expr_Type);
            pragma Assert (Done or else Serious_Errors_Detected > 0);
            return Result;
         end Component_Bounds_Info;

         Component_Bounds : constant Composite_Range_Info
           := Component_Bounds_Info;

         package Case_Bindings is

            procedure Note_Binding
              (Comp_Assoc : Node_Id;
               Choice     : Node_Id;
               Alt        : Node_Id);
            --  Note_Binding is called once for each component association
            --  that defines a binding (using either "A => B is X" or
            --  "A => <X>" syntax);

            procedure Check_Bindings;
            --  After all calls to Note_Binding, check that bindings are
            --  ok (e.g., check consistency among different choices of
            --  one alternative).

         end Case_Bindings;

         procedure Refresh_Binding_Info (Aggr : Node_Id);
         --  The parser records binding-related info in the tree.
         --  The choice nodes that we see here might not be (will never be?)
         --  the original nodes that were produced by the parser. The info
         --  recorded by the parser is missing in that case, so this
         --  procedure recovers it.
         --
         --  There are bugs here. In some cases involving nested aggregates,
         --  the path back to the parser-created nodes is lost. In particular,
         --  we may fail to detect an illegal case like
         --   when (F1 | F2 => (Aa => Natural, Bb => Natural is X)) =>
         --  This should be rejected because it is binding X to both the
         --  F1.Bb and to the F2.Bb subcomponents of the case selector.
         --  It would be nice if the not-specific-to-pattern-matching
         --  aggregate-processing code could remain unaware of the existence
         --  of this binding-related info but perhaps that isn't possible.

         --------------------------
         -- Refresh_Binding_Info --
         --------------------------

         procedure Refresh_Binding_Info (Aggr : Node_Id) is
            Orig_Aggr : constant Node_Id := Original_Node (Aggr);
            Orig_Comp : Node_Id := First (Component_Associations (Orig_Aggr));
         begin
            if Aggr = Orig_Aggr then
               return;
            end if;

            while Present (Orig_Comp) loop
               if Nkind (Orig_Comp) = N_Component_Association
                 and then Binding_Chars (Orig_Comp) /= No_Name
               then
                  if List_Length (Choices (Orig_Comp)) /= 1 then
                     --  Conceivably this could be checked during parsing,
                     --  but checking is easier here.

                     Error_Msg_N
                       ("binding shared by multiple components", Orig_Comp);
                     return;
                  end if;

                  declare
                     Orig_Name : constant Name_Id :=
                       Chars (First (Choices (Orig_Comp)));
                     Comp : Node_Id := First (Component_Associations (Aggr));
                     Matching_Comp : Node_Id := Empty;
                  begin
                     while Present (Comp) loop
                        if Chars (First (Choices (Comp))) = Orig_Name then
                           pragma Assert (not Present (Matching_Comp));
                           Matching_Comp := Comp;
                        end if;

                        Next (Comp);
                     end loop;

                     pragma Assert (Present (Matching_Comp));

                     Set_Binding_Chars
                       (Matching_Comp,
                        Binding_Chars (Orig_Comp));
                  end;
               end if;

               Next (Orig_Comp);
            end loop;
         end Refresh_Binding_Info;

         ------------------
         -- Parse_Choice --
         ------------------

         function Parse_Choice (Choice : Node_Id;
                                Alt    : Node_Id) return Choice_Range_Info
         is
            Result    : Choice_Range_Info (Is_Others => False);
            Ranges    : Composite_Range_Info renames Result.Ranges;
            Next_Part : Part_Id'Base range 1 .. Part_Id'Last + 1 := 1;

            procedure Traverse_Choice (Expr : Node_Id);
            --  Traverse a legal choice expression, looking for
            --  values/ranges of discrete parts. Call Update_Result
            --  for each.

            procedure Update_Result (Discrete_Range : Discrete_Range_Info);
            --  Initialize first remaining uninitialized element of Ranges.
            --  Also set Next_Part.

            procedure Update_Result_For_Full_Coverage (Comp_Type  : Entity_Id);
            --  For each scalar part of the given component type, call
            --  Update_Result with the full range for that scalar part.
            --  This is used for both box components in aggregates and
            --  for any inactive-variant components that do not appear in
            --  a given aggregate.

            -------------------
            -- Update_Result --
            -------------------

            procedure Update_Result (Discrete_Range : Discrete_Range_Info) is
            begin
               Ranges (Next_Part) := Discrete_Range;
               Next_Part := Next_Part + 1;
            end Update_Result;

            -------------------------------------
            -- Update_Result_For_Full_Coverage --
            -------------------------------------

            procedure Update_Result_For_Full_Coverage (Comp_Type : Entity_Id)
            is
            begin
               for Counter in 1 .. Scalar_Part_Count (Comp_Type) loop
                  Update_Result (Component_Bounds (Next_Part));
               end loop;
            end Update_Result_For_Full_Coverage;

            ---------------------
            -- Traverse_Choice --
            ---------------------

            procedure Traverse_Choice (Expr : Node_Id) is
            begin
               if Nkind (Expr) = N_Qualified_Expression then
                  Traverse_Choice (Expression (Expr));

               elsif Nkind (Expr) = N_Type_Conversion
                  and then not Comes_From_Source (Expr)
               then
                  if Expr /= Original_Node (Expr) then
                     Traverse_Choice (Original_Node (Expr));
                  else
                     Traverse_Choice (Expression (Expr));
                  end if;

               elsif Nkind (Expr) = N_Aggregate then
                  if Is_Record_Type (Etype (Expr)) then
                     Refresh_Binding_Info (Aggr => Expr);

                     declare
                        Comp_Assoc : Node_Id :=
                          First (Component_Associations (Expr));
                        --  Aggregate has been normalized (components in
                        --  order, only one component per choice, etc.).

                        Comp_From_Type : Node_Id :=
                          First_Component_Or_Discriminant
                            (Base_Type (Etype (Expr)));

                        Saved_Next_Part : constant Part_Id := Next_Part;
                     begin
                        while Present (Comp_Assoc) loop
                           pragma Assert
                             (List_Length (Choices (Comp_Assoc)) = 1);

                           declare
                              Comp : constant Node_Id :=
                                Entity (First (Choices (Comp_Assoc)));
                              Comp_Seen : Boolean := False;
                           begin
                              loop
                                 if Original_Record_Component (Comp) =
                                   Original_Record_Component (Comp_From_Type)
                                 then
                                    Comp_Seen := True;
                                 else
                                    --  We have an aggregate of a type that
                                    --  has a variant part (or has a
                                    --  subcomponent type that has a variant
                                    --  part) and we have to deal with a
                                    --  component that is present in the type
                                    --  but not in the aggregate (because the
                                    --  component is in an inactive variant).
                                    --
                                    Update_Result_For_Full_Coverage
                                      (Comp_Type => Etype (Comp_From_Type));
                                 end if;

                                 Comp_From_Type :=
                                   Next_Component_Or_Discriminant
                                     (Comp_From_Type);

                                 exit when Comp_Seen;
                              end loop;
                           end;

                           declare
                              Comp_Type : constant Entity_Id :=
                                Etype (First (Choices (Comp_Assoc)));
                           begin
                              if Box_Value_Required (Comp_Type) then
                                 --  This component is not allowed to
                                 --  influence which alternative is
                                 --  chosen; case choice must be box.
                                 --
                                 --  For example, component might be
                                 --  of a real type or of an access type
                                 --  or of a non-static discrete subtype.
                                 if not Box_Present (Comp_Assoc) then
                                    Error_Msg_N
                                      ("Non-box case choice component value" &
                                         " of unsupported type/subtype",
                                       Expression (Comp_Assoc));
                                 end if;
                              elsif Box_Present (Comp_Assoc) then
                                 --  Box matches all values
                                 Update_Result_For_Full_Coverage
                                   (Etype (First (Choices (Comp_Assoc))));
                              else
                                 Traverse_Choice (Expression (Comp_Assoc));
                              end if;
                           end;

                           if Binding_Chars (Comp_Assoc) /= No_Name
                           then
                              Case_Bindings.Note_Binding
                                (Comp_Assoc => Comp_Assoc,
                                 Choice     => Choice,
                                 Alt        => Alt);
                           end if;

                           Next (Comp_Assoc);
                        end loop;

                        while Present (Comp_From_Type) loop
                           --  Deal with any trailing inactive-variant
                           --  components.
                           --
                           --  See earlier commment about calling
                           --  Update_Result_For_Full_Coverage for such
                           --  components.

                           Update_Result_For_Full_Coverage
                             (Comp_Type => Etype (Comp_From_Type));

                           Comp_From_Type :=
                             Next_Component_Or_Discriminant (Comp_From_Type);
                        end loop;

                        declare
                           Expr_Type : Entity_Id := Etype (Expr);
                        begin
                           if Has_Discriminants (Expr_Type) then
                              --  Avoid nonstatic choice expr types,
                              --  for which Scalar_Part_Count returns 0.
                              Expr_Type := Base_Type (Expr_Type);
                           end if;

                           pragma Assert
                             (Nat (Next_Part - Saved_Next_Part)
                               = Scalar_Part_Count (Expr_Type));
                        end;
                     end;
                  elsif Is_Array_Type (Etype (Expr)) then
                     if Is_Non_Empty_List (Component_Associations (Expr)) then
                        Error_Msg_N
                          ("non-positional array aggregate as/within case "
                           & "choice not implemented", Expr);
                     end if;

                     if not Unconstrained_Array_Case
                        and then List_Length (Expressions (Expr))
                           /= Nat (Part_Id'Last)
                     then
                        Error_Msg_Uint_1 := UI_From_Int
                          (List_Length (Expressions (Expr)));
                        Error_Msg_Uint_2 := UI_From_Int (Int (Part_Id'Last));
                        Error_Msg_N
                          ("array aggregate length ^ does not match length " &
                           "of statically constrained case selector ^", Expr);
                        return;
                     end if;

                     declare
                        Subexpr : Node_Id := First (Expressions (Expr));
                     begin
                        while Present (Subexpr) loop
                           Traverse_Choice (Subexpr);
                           Next (Subexpr);
                        end loop;
                     end;
                  else
                     raise Program_Error;
                  end if;
               elsif Nkind (Expr) = N_String_Literal then
                  if not Is_Array_Type (Etype (Expr)) then
                     Error_Msg_N
                       ("User-defined string literal not allowed as/within"
                        & "case choice", Expr);
                  else
                     declare
                        Char_Type : constant Entity_Id :=
                          Root_Type (Component_Type (Etype (Expr)));

                        --  If the component type is not a standard character
                        --  type then this string lit should have already been
                        --  transformed into an aggregate in
                        --  Resolve_String_Literal.
                        --
                        pragma Assert (Is_Standard_Character_Type (Char_Type));

                        Str      : constant String_Id := Strval (Expr);
                        Strlen   : constant Nat       := String_Length (Str);
                        Char_Val : Uint;
                     begin
                        if not Unconstrained_Array_Case
                           and then Strlen /= Nat (Part_Id'Last)
                        then
                           Error_Msg_Uint_1 := UI_From_Int (Strlen);
                           Error_Msg_Uint_2 := UI_From_Int
                             (Int (Part_Id'Last));
                           Error_Msg_N
                             ("String literal length ^ does not match length" &
                              " of statically constrained case selector ^",
                              Expr);
                           return;
                        end if;

                        for Idx in 1 .. Strlen loop
                           Char_Val :=
                             UI_From_CC (Get_String_Char (Str, Idx));
                           Update_Result ((Low | High => Char_Val));
                        end loop;
                     end;
                  end if;
               elsif Is_Discrete_Type (Etype (Expr)) then
                  if Nkind (Expr) in N_Has_Entity
                    and then Present (Entity (Expr))
                    and then Is_Type (Entity (Expr))
                  then
                     declare
                        Low  : constant Node_Id :=
                          Type_Low_Bound (Entity (Expr));
                        High : constant Node_Id :=
                          Type_High_Bound (Entity (Expr));
                     begin
                        Update_Result ((Low  => Expr_Value (Low),
                                        High => Expr_Value (High)));
                     end;
                  else
                     pragma Assert (Compile_Time_Known_Value (Expr));
                     Update_Result ((Low | High => Expr_Value (Expr)));
                  end if;
               elsif Nkind (Expr) in N_Has_Entity
                 and then Present (Entity (Expr))
                 and then Ekind (Entity (Expr)) = E_Constant
               then
                  Traverse_Choice (Expression (Parent (Entity (Expr))));
               elsif Nkind (Original_Node (Expr))
                       in N_Aggregate | N_String_Literal
               then
                  Traverse_Choice (Original_Node (Expr));
               else
                  Error_Msg_N
                    ("non-aggregate case choice (or subexpression thereof)"
                     & " that is not of a discrete type not implemented",
                     Expr);
               end if;
            end Traverse_Choice;

         --  Start of processing for Parse_Choice

         begin
            if Nkind (Choice) = N_Others_Choice then
               return (Is_Others => True);
            end if;

            if Unconstrained_Array_Case then
               --  Treat length like a discriminant
               Update_Result ((Low | High =>
                                 UI_From_Int (Array_Choice_Length (Choice))));
            end if;

            Traverse_Choice (Choice);

            if Unconstrained_Array_Case then
               --  This is somewhat tricky. Suppose we are casing on String,
               --  the longest choice in the case statement is length 10, and
               --  the choice we are looking at now is of length 6. We fill
               --  in the trailing 4 slots here.
               while Next_Part <= Part_Id'Last loop
                  Update_Result_For_Full_Coverage
                    (Comp_Type => Component_Type (Case_Expr_Type));
               end loop;
            end if;

            --  Avoid returning uninitialized garbage in error case
            if Next_Part /= Part_Id'Last + 1 then
               pragma Assert (Serious_Errors_Detected > 0);
               Result.Ranges := (others => (Low => Uint_1, High => Uint_0));
            end if;

            return Result;
         end Parse_Choice;

         package body Case_Bindings is

            type Binding is record
               Comp_Assoc : Node_Id;
               Choice     : Node_Id;
               Alt        : Node_Id;
            end record;

            type Binding_Index is new Natural;

            package Case_Bindings_Table is new Table.Table
              (Table_Component_Type => Binding,
               Table_Index_Type     => Binding_Index,
               Table_Low_Bound      => 1,
               Table_Initial        => 16,
               Table_Increment      => 64,
               Table_Name           => "Composite_Case_Ops.Case_Bindings");

            ------------------
            -- Note_Binding --
            ------------------

            procedure Note_Binding
              (Comp_Assoc : Node_Id;
               Choice     : Node_Id;
               Alt        : Node_Id)
            is
            begin
               Case_Bindings_Table.Append
                 ((Comp_Assoc => Comp_Assoc,
                   Choice     => Choice,
                   Alt        => Alt));
            end Note_Binding;

            --------------------
            -- Check_Bindings --
            --------------------

            procedure Check_Bindings
            is
               use Case_Bindings_Table;

               function Binding_Subtype (Idx : Binding_Index;
                                         Tab : Table_Type)
                 return Entity_Id is
                 (Etype (Nlists.First (Choices (Tab (Idx).Comp_Assoc))));

               procedure Declare_Binding_Objects
                  (Alt_Start             : Binding_Index;
                   Alt                   : Node_Id;
                   First_Choice_Bindings : Natural;
                   Tab                   : Table_Type);
               --  Declare the binding objects for a given alternative

               ------------------------------
               --  Declare_Binding_Objects --
               ------------------------------

               procedure Declare_Binding_Objects
                  (Alt_Start             : Binding_Index;
                   Alt                   : Node_Id;
                   First_Choice_Bindings : Natural;
                   Tab                   : Table_Type)
               is
                  Loc : constant Source_Ptr := Sloc (Alt);
                  Declarations : constant List_Id := New_List;
                  Decl         : Node_Id;
                  Obj_Type     : Entity_Id;
                  Def_Id       : Entity_Id;
               begin
                  for FC_Idx in Alt_Start ..
                    Alt_Start + Binding_Index (First_Choice_Bindings - 1)
                  loop
                     Obj_Type := Binding_Subtype (FC_Idx, Tab);
                     Def_Id := Make_Defining_Identifier
                                 (Loc,
                                  Binding_Chars (Tab (FC_Idx).Comp_Assoc));

                     --  Either make a copy or rename the original. At a
                     --  minimum, we do not want a copy if it would need
                     --  finalization. Copies may also introduce problems
                     --  if default init can have side effects (although we
                     --  could suppress such default initialization).
                     --  We have to make a copy in any cases where
                     --  Unrestricted_Access doesn't work.
                     --
                     --  This is where the copy-or-rename decision is made.
                     --  In many cases either way would work and so we have
                     --  some flexibility here.

                     if not Is_By_Copy_Type (Obj_Type) then
                        --  Generate
                        --     type Ref
                        --       is access constant Obj_Type;
                        --     Ptr : Ref := <some bogus value>;
                        --     Obj : Obj_Type renames Ptr.all;
                                       --
                        --  Initialization of Ptr will be generated later
                        --  during expansion.

                        declare
                           Ptr_Type : constant Entity_Id :=
                             Make_Temporary (Loc, 'P');

                           Ptr_Type_Def : constant Node_Id :=
                             Make_Access_To_Object_Definition (Loc,
                               All_Present => True,
                               Subtype_Indication =>
                                 New_Occurrence_Of (Obj_Type, Loc));

                           Ptr_Type_Decl : constant Node_Id :=
                             Make_Full_Type_Declaration (Loc,
                               Ptr_Type,
                               Type_Definition => Ptr_Type_Def);

                           Ptr_Obj : constant Entity_Id :=
                             Make_Temporary (Loc, 'T');

                           --  We will generate initialization code for this
                           --  object later (during expansion) but in the
                           --  meantime we don't want the dereference that
                           --  is generated a few lines below here to be
                           --  transformed into a Raise_C_E. To prevent this,
                           --  we provide a bogus initial value here; this
                           --  initial value will be removed later during
                           --  expansion.

                           Ptr_Obj_Decl : constant Node_Id :=
                             Make_Object_Declaration
                               (Loc, Ptr_Obj,
                                Object_Definition =>
                                  New_Occurrence_Of (Ptr_Type, Loc),
                                Expression =>
                                  Unchecked_Convert_To
                                    (Ptr_Type,
                                     Make_Integer_Literal (Loc, 5432)));
                        begin
                           Mutate_Ekind (Ptr_Type, E_Access_Type);

                           --  in effect, Storage_Size => 0
                           Set_No_Pool_Assigned (Ptr_Type);

                           Set_Is_Access_Constant (Ptr_Type);

                           --  We could set Ptr_Type'Alignment here if that
                           --  ever turns out to be needed for renaming a
                           --  misaligned subcomponent.

                           Mutate_Ekind (Ptr_Obj, E_Variable);
                           Set_Etype (Ptr_Obj, Ptr_Type);

                           Decl :=
                             Make_Object_Renaming_Declaration
                               (Loc, Def_Id,
                                Subtype_Mark =>
                                  New_Occurrence_Of (Obj_Type, Loc),
                                Name =>
                                  Make_Explicit_Dereference
                                    (Loc, New_Occurrence_Of (Ptr_Obj, Loc)));

                           Append_To (Declarations, Ptr_Type_Decl);
                           Append_To (Declarations, Ptr_Obj_Decl);
                        end;
                     else
                        Decl := Make_Object_Declaration
                          (Sloc => Loc,
                           Defining_Identifier => Def_Id,
                           Object_Definition =>
                              New_Occurrence_Of (Obj_Type, Loc));
                     end if;
                     Append_To (Declarations, Decl);
                  end loop;

                  declare
                     Old_Statements : constant List_Id := Statements (Alt);
                     New_Statements : constant List_Id := New_List;

                     Block_Statement : constant Node_Id :=
                       Make_Block_Statement (Sloc => Loc,
                         Declarations => Declarations,
                         Handled_Statement_Sequence =>
                           Make_Handled_Sequence_Of_Statements
                             (Loc, Old_Statements),
                         Has_Created_Identifier => True);
                  begin
                     Append_To (New_Statements, Block_Statement);
                     Set_Statements (Alt, New_Statements);
                  end;
               end Declare_Binding_Objects;
            begin
               if Last = 0 then
                  --  no bindings to check
                  return;
               end if;

               declare
                  Tab : Table_Type
                          renames Case_Bindings_Table.Table (1 .. Last);

                  function Same_Id (Idx1, Idx2 : Binding_Index)
                    return Boolean is (
                    Binding_Chars (Tab (Idx1).Comp_Assoc) =
                    Binding_Chars (Tab (Idx2).Comp_Assoc));
               begin
                  --  Verify that elements with given choice or alt value
                  --  are contiguous, and that elements with equal
                  --  choice values have same alt value.

                  for Idx1 in 2 .. Tab'Last loop
                     if Tab (Idx1 - 1).Choice /= Tab (Idx1).Choice then
                        pragma Assert
                          (for all Idx2 in Idx1 + 1 .. Tab'Last =>
                             Tab (Idx2).Choice /= Tab (Idx1 - 1).Choice);
                     else
                        pragma Assert (Tab (Idx1 - 1).Alt = Tab (Idx1).Alt);
                     end if;
                     if Tab (Idx1 - 1).Alt /= Tab (Idx1).Alt then
                        pragma Assert
                          (for all Idx2 in Idx1 + 1 .. Tab'Last =>
                             Tab (Idx2).Alt /= Tab (Idx1 - 1).Alt);
                     end if;
                  end loop;

                  --  Check for user errors:
                  --  1) Two choices for a given alternative shall define the
                  --     same set of names. Can't have
                  --        when (<X>, 0) | (0, <Y>) =>
                  --  2) A choice shall not define a name twice. Can't have
                  --        when (A => <X>, B => <X>, C => 0) =>
                  --  3) Two definitions of a name within one alternative
                  --     shall have statically matching component subtypes.
                  --     Can't have
                  --        type R is record Int : Integer;
                  --                         Nat : Natural; end record;
                  --        case R'(...) is
                  --          when (<X>, 1) | (1, <X>) =>
                  --  4) A given binding shall match only one value.
                  --     Can't have
                  --         (Fld1 | Fld2 => (Fld => <X>))
                  --     For now, this is enforced *very* conservatively
                  --     with respect to arrays - a binding cannot match
                  --     any part of an array. This is temporary.

                  for Idx1 in Tab'Range loop
                     if Idx1 = 1
                       or else Tab (Idx1 - 1).Alt /= Tab (Idx1).Alt
                     then
                        --  Process one alternative
                        declare
                           Alt_Start : constant Binding_Index := Idx1;
                           Alt : constant Node_Id := Tab (Alt_Start).Alt;

                           First_Choice : constant Node_Id :=
                             Nlists.First (Discrete_Choices (Alt));
                           First_Choice_Bindings : Natural := 0;
                        begin
                           --  Check for duplicates within one choice,
                           --  and for choices with no bindings.

                           if First_Choice /= Tab (Alt_Start).Choice then
                              Error_Msg_N ("binding(s) missing for choice",
                                           First_Choice);
                              return;
                           end if;

                           declare
                              Current_Choice : Node_Id := First_Choice;
                              Choice_Start : Binding_Index := Alt_Start;
                           begin
                              for Idx2 in Alt_Start .. Tab'Last loop
                                 exit when Tab (Idx2).Alt /= Alt;
                                 if Tab (Idx2).Choice = Current_Choice then
                                    for Idx3 in Choice_Start .. Idx2 - 1 loop
                                       if Same_Id (Idx2, Idx3)
                                       then
                                          Error_Msg_N
                                            ("duplicate binding in choice",
                                             Current_Choice);
                                          return;
                                       end if;
                                    end loop;
                                 else
                                    Next (Current_Choice);
                                    pragma Assert (Present (Current_Choice));
                                    Choice_Start := Idx2;

                                    if Tab (Idx2).Choice /= Current_Choice
                                    then
                                       Error_Msg_N
                                         ("binding(s) missing for choice",
                                          Current_Choice);
                                       return;
                                    end if;
                                 end if;
                              end loop;

                              --  If we made it through all the bindings
                              --  for this alternative but didn't make it
                              --  to the last choice, then bindings are
                              --  missing for all remaining choices.
                              --  We only complain about the first one.

                              if Present (Next (Current_Choice)) then
                                 Error_Msg_N
                                   ("binding(s) missing for choice",
                                     Next (Current_Choice));
                                 return;
                              end if;
                           end;

                           --  Count bindings for first choice of alternative

                           for FC_Idx in Alt_Start .. Tab'Last loop
                              exit when Tab (FC_Idx).Choice /= First_Choice;
                              First_Choice_Bindings :=
                                First_Choice_Bindings + 1;
                           end loop;

                           declare
                              Current_Choice : Node_Id := First_Choice;
                              Current_Choice_Bindings : Natural := 0;
                           begin
                              for Idx2 in Alt_Start .. Tab'Last loop
                                 exit when Tab (Idx2).Alt /= Alt;

                                 --  If starting a new choice

                                 if Tab (Idx2).Choice /= Current_Choice then

                                    --  Check count for choice just finished

                                    if Current_Choice_Bindings
                                      /= First_Choice_Bindings
                                    then
                                       Error_Msg_N
                                         ("subsequent choice has different"
                                          & " number of bindings than first"
                                          & " choice", Current_Choice);
                                    end if;

                                    Current_Choice := Tab (Idx2).Choice;
                                    Current_Choice_Bindings := 1;

                                    --  Remember that Alt has both one or more
                                    --  bindings and two or more choices; we'll
                                    --  need to know this during expansion.

                                    Set_Multidefined_Bindings (Alt, True);
                                 else
                                    Current_Choice_Bindings :=
                                      Current_Choice_Bindings + 1;
                                 end if;

                                 --  Check that first choice has binding with
                                 --  matching name; check subtype consistency.

                                 declare
                                    Found : Boolean := False;
                                 begin
                                    for FC_Idx in
                                      Alt_Start ..
                                      Alt_Start + Binding_Index
                                                    (First_Choice_Bindings - 1)
                                    loop
                                       if Same_Id (Idx2, FC_Idx) then
                                          if not Subtypes_Statically_Match
                                            (Binding_Subtype (Idx2, Tab),
                                             Binding_Subtype (FC_Idx, Tab))
                                          then
                                             Error_Msg_N
                                               ("subtype of binding in "
                                                & "subsequent choice does not "
                                                & "match that in first choice",
                                                Tab (Idx2).Comp_Assoc);
                                          end if;
                                          Found := True;
                                          exit;
                                       end if;
                                    end loop;

                                    if not Found then
                                       Error_Msg_N
                                         ("binding defined in subsequent "
                                          & "choice not defined in first "
                                          & "choice", Current_Choice);
                                    end if;
                                 end;

                                 --  Check for illegal repeated binding
                                 --  via an enclosing aggregate, as in
                                 --  (F1 | F2 => (F3 => Natural is X,
                                 --               F4 => Natural))
                                 --  where the inner aggregate would be ok.

                                 declare
                                    Rover : Node_Id := Tab (Idx2).Comp_Assoc;
                                 begin
                                    while Rover /= Tab (Idx2).Choice loop
                                       Rover :=
                                         (if Is_List_Member (Rover) then
                                            Parent (List_Containing (Rover))
                                          else Parent (Rover));
                                       pragma Assert (Present (Rover));
                                       if Nkind (Rover)
                                         = N_Component_Association
                                         and then List_Length (Choices (Rover))
                                         > 1
                                       then
                                          Error_Msg_N
                                            ("binding shared by multiple "
                                                & "enclosing components",
                                             Tab (Idx2).Comp_Assoc);
                                       end if;
                                    end loop;
                                 end;
                              end loop;
                           end;

                           --  Construct the (unanalyzed) declarations for
                           --  the current alternative. Then analyze them.

                           if First_Choice_Bindings > 0 then
                              Declare_Binding_Objects
                                (Alt_Start             => Alt_Start,
                                 Alt                   => Alt,
                                 First_Choice_Bindings =>
                                   First_Choice_Bindings,
                                 Tab                   => Tab);
                           end if;
                        end;
                     end if;
                  end loop;
               end;
            end Check_Bindings;
         end Case_Bindings;

         function Choice_Bounds_Info return Choices_Range_Info;
         --  Returns mapping from any given Choice_Id value to that choice's
         --  component-to-range map.

         ------------------------
         -- Choice_Bounds_Info --
         ------------------------

         function Choice_Bounds_Info return Choices_Range_Info is
            Result : Choices_Range_Info;
            Alt    : Node_Id := First (Alternatives (Case_Statement));
            C_Id   : Choice_Id := 1;
         begin
            while Present (Alt) loop
               declare
                  Choice : Node_Id := First (Discrete_Choices (Alt));
               begin
                  while Present (Choice) loop
                     Result (C_Id) := Parse_Choice (Choice, Alt => Alt);

                     Next (Choice);
                     if C_Id /= Choice_Id'Last then
                        C_Id := C_Id + 1;
                     end if;
                  end loop;
               end;
               Next (Alt);
            end loop;

            pragma Assert (C_Id = Choice_Id'Last);

            --  No more calls to Note_Binding, so time for checks.
            Case_Bindings.Check_Bindings;

            return Result;
         end Choice_Bounds_Info;

         Choices_Bounds : constant Choices_Range_Info := Choice_Bounds_Info;

         package body Value_Sets is
            use GNAT;

            function Hash (Key : Uint) return Bucket_Range_Type is
              (Bucket_Range_Type
                 (UI_To_Int (Key mod (Uint_2 ** Uint_31))));

            package Uint_Sets is new GNAT.Sets.Membership_Sets
              (Uint, "=", Hash);

            type Representative_Values_Array is
              array (Part_Id) of Uint_Sets.Membership_Set;

            function Representative_Values_Init
              return Representative_Values_Array;
            --  Select the representative values for each Part_Id value.
            --  This function is called exactly once, immediately after it
            --  is declared.

            --------------------------------
            -- Representative_Values_Init --
            --------------------------------

            function Representative_Values_Init
              return Representative_Values_Array
            is
               --  For each range of each choice (as well as the range for the
               --  component subtype, which is handled in the first loop),
               --  insert the low bound of the range and the successor of
               --  the high bound into the corresponding R_V element.
               --
               --  The idea we are trying to capture here is somewhat tricky.
               --  Given an arbitrary point P1 in the Cartesian product
               --  of the Component_Bounds sets, we want to be able
               --  to map that to a point P2 in the (smaller) Cartesian product
               --  of the Representative_Values sets that has the property
               --  that for every choice of the case statement, P1 matches
               --  the choice if and only if P2 also matches. Given that,
               --  we can implement the overlapping/containment/etc. rules
               --  safely by just looking at (using brute force enumeration)
               --  the (smaller) Cartesian product of the R_V sets.
               --  We are never going to actually perform this point-to-point
               --  mapping - just the fact that it exists is enough to ensure
               --  we can safely look at just the R_V sets.
               --
               --  The desired mapping can be implemented by mapping a point
               --  P1 to a point P2 by reducing each of P1's coordinates down
               --  to the largest element of the corresponding R_V set that is
               --  less than or equal to the original coordinate value (such
               --  an element Y will always exist because the R_V set for a
               --  given component always includes the low bound of the
               --  component subtype). It then suffices to show that every
               --  choice in the case statement yields the same Boolean result
               --  for P1 as for P2.
               --
               --  Suppose the contrary. Then there is some particular
               --  coordinate position X (i.e., a Part_Id value) and some
               --  choice C where exactly one of P1(X) and P2(X) belongs to
               --  the (contiguous) range associated with C(X); call that
               --  range L .. H. We know that P2(X) <= P1(X) because the
               --  mapping never increases coordinate values. Consider three
               --  cases: P1(X) lies within the L .. H range, or it is greater
               --  than H, or it is lower than L.
               --  The third case is impossible because reducing a value that
               --  is less than L can only produce another such value,
               --  violating the "exactly one" assumption. The second
               --  case is impossible because L belongs to the corresponding
               --  R_V set, so P2(X) >= L and both values belong to the
               --  range, again violating the "exactly one" assumption.
               --  Finally, the third case is impossible because H+1 belongs
               --  to the corresponding R_V set, so P2(X) > H, so neither
               --  value belongs to the range, again violating the "exactly
               --  one" assumption. So our initial supposition was wrong. QED.

               use Uint_Sets;

               Result : constant Representative_Values_Array
                 := (others => Uint_Sets.Create (Initial_Size => 32));

               procedure Insert_Representative (Value : Uint; P : Part_Id);
               --  Insert the given Value into the representative values set
               --  for the given component if it belongs to the component's
               --  subtype. Otherwise, do nothing.

               ---------------------------
               -- Insert_Representative --
               ---------------------------

               procedure Insert_Representative (Value : Uint; P : Part_Id) is
               begin
                  if Value >= Component_Bounds (P).Low and
                    Value <= Component_Bounds (P).High
                  then
                     Insert (Result (P), Value);
                  end if;
               end Insert_Representative;

            begin
               for P in Part_Id loop
                  Insert_Representative (Component_Bounds (P).Low, P);
               end loop;

               if Simplified_Composite_Coverage_Rules then
                  --  Omit other representative values to avoid capacity
                  --  problems building data structures only used in
                  --  compile-time checks that will not be performed.
                  return Result;
               end if;

               for C of Choices_Bounds loop
                  if not C.Is_Others then
                     for P in Part_Id loop
                        if C.Ranges (P).Low <= C.Ranges (P).High then
                           Insert_Representative (C.Ranges (P).Low, P);
                           Insert_Representative (C.Ranges (P).High + 1, P);
                        end if;
                     end loop;
                  end if;
               end loop;
               return Result;
            end Representative_Values_Init;

            Representative_Values : constant Representative_Values_Array
              := Representative_Values_Init;
            --  We want to avoid looking at every point in the Cartesian
            --  product of all component values. Instead we select, for each
            --  component, a set of representative values and then look only
            --  at the Cartesian product of those sets. A single value can
            --  safely represent a larger enclosing interval if every choice
            --  for that component either completely includes or completely
            --  excludes the interval. The elements of this array will be
            --  populated by a call to Initialize_Representative_Values and
            --  will remain constant after that.

            type Value_Index_Base is new Natural;

            function Value_Index_Count return Value_Index_Base;
            --  Returns the product of the sizes of the Representative_Values
            --  sets (i.e., the size of the Cartesian product of the sets).
            --  May return zero if one of the sets is empty.
            --  This function is called exactly once, immediately after it
            --  is declared.

            -----------------------
            -- Value_Index_Count --
            -----------------------

            function Value_Index_Count return Value_Index_Base is
               Result : Value_Index_Base := 1;
            begin
               for Set of Representative_Values loop
                  Result := Result * Value_Index_Base (Uint_Sets.Size (Set));
               end loop;
               return Result;
            exception
               when Constraint_Error =>
                  Error_Msg_N
                    ("Capacity exceeded in compiling case statement with"
                      & " composite selector type", Case_Statement);
                  raise;
            end Value_Index_Count;

            Max_Value_Index : constant Value_Index_Base := Value_Index_Count;

            subtype Value_Index is Value_Index_Base range 1 .. Max_Value_Index;
            type Value_Index_Set is array (Value_Index) of Boolean;

            package Value_Index_Set_Table is new Table.Table
              (Table_Component_Type => Value_Index_Set,
               Table_Index_Type     => Value_Set,
               Table_Low_Bound      => 1,
               Table_Initial        => 16,
               Table_Increment      => 100,
               Table_Name           => "Composite_Case_Ops.Value_Sets");
            --  A nonzero Value_Set value is an index into this table.

            function Indexed (Index : Value_Set) return Value_Index_Set
              is (Value_Index_Set_Table.Table.all (Index));

            function Allocate_Table_Element (Initial_Value : Value_Index_Set)
              return Value_Set;
            --  Allocate and initialize a new table element; return its index.

            ----------------------------
            -- Allocate_Table_Element --
            ----------------------------

            function Allocate_Table_Element (Initial_Value : Value_Index_Set)
              return Value_Set
            is
               use Value_Index_Set_Table;
            begin
               Append (Initial_Value);
               return Last;
            end Allocate_Table_Element;

            procedure Assign_Table_Element (Index : Value_Set;
                                            Value : Value_Index_Set);
            --  Assign specified value to specified table element.

            --------------------------
            -- Assign_Table_Element --
            --------------------------

            procedure Assign_Table_Element (Index : Value_Set;
                                            Value : Value_Index_Set)
            is
            begin
               Value_Index_Set_Table.Table.all (Index) := Value;
            end Assign_Table_Element;

            -------------
            -- Compare --
            -------------

            function Compare (S1, S2 : Value_Set) return Set_Comparison is
            begin
               if S1 = Empty or S2 = Empty then
                  return Disjoint;
               elsif Indexed (S1) = Indexed (S2) then
                  return Equal;
               else
                  declare
                     Intersection : constant Value_Index_Set
                       := Indexed (S1) and Indexed (S2);
                  begin
                     if (for all Flag of Intersection => not Flag) then
                        return Disjoint;
                     elsif Intersection = Indexed (S1) then
                        return Contained_By;
                     elsif Intersection = Indexed (S2) then
                        return Contains;
                     else
                        return Overlaps;
                     end if;
                  end;
               end if;
            end Compare;

            -------------------------
            -- Complement_Is_Empty --
            -------------------------

            function Complement_Is_Empty (Set : Value_Set) return Boolean
              is (Set /= Empty
                  and then (for all Flag of Indexed (Set) => Flag));

            ---------------------
            -- Free_Value_Sets --
            ---------------------

            procedure Free_Value_Sets is
            begin
               Value_Index_Set_Table.Free;
            end Free_Value_Sets;

            -----------
            -- Union --
            -----------

            procedure Union (Target : in out Value_Set; Source : Value_Set) is
            begin
               if Source /= Empty then
                  if Target = Empty then
                     Target := Allocate_Table_Element (Indexed (Source));
                  else
                     Assign_Table_Element
                       (Target, Indexed (Target) or Indexed (Source));
                  end if;
               end if;
            end Union;

            ------------
            -- Remove --
            ------------

            procedure Remove (Target : in out Value_Set; Source : Value_Set) is
            begin
               if Source /= Empty and Target /= Empty then
                  Assign_Table_Element
                    (Target, Indexed (Target) and not Indexed (Source));
                  if (for all V of Indexed (Target) => not V) then
                     Target := Empty;
                  end if;
               end if;
            end Remove;

            ---------------------
            -- Matching_Values --
            ---------------------

            function Matching_Values
              (Info : Composite_Range_Info) return Value_Set
            is
               Matches    : Value_Index_Set;
               Next_Index : Value_Index := 1;
               Done       : Boolean := False;
               Point      : array (Part_Id) of Uint;

               procedure Test_Point_For_Match;
               --  Point identifies a point in the Cartesian product of the
               --  representative value sets. Record whether that Point
               --  belongs to the product-of-ranges specified by Info.

               --------------------------
               -- Test_Point_For_Match --
               --------------------------

               procedure Test_Point_For_Match is
                  function In_Range (Val : Uint; Rang : Discrete_Range_Info)
                    return Boolean is
                    ((Rang.Low <= Val) and then (Val <= Rang.High));
               begin
                  pragma Assert (not Done);
                  Matches (Next_Index) :=
                    (for all P in Part_Id => In_Range (Point (P), Info (P)));
                  if Next_Index = Matches'Last then
                     Done := True;
                  else
                     Next_Index := Next_Index + 1;
                  end if;
               end Test_Point_For_Match;

               procedure Test_Points (P : Part_Id);
               --  Iterate over the Cartesian product of the representative
               --  value sets, calling Test_Point_For_Match for each point.

               -----------------
               -- Test_Points --
               -----------------

               procedure Test_Points (P : Part_Id) is
                  use Uint_Sets;
                  Iter : Iterator := Iterate (Representative_Values (P));
               begin
                  --  We could traverse here in sorted order, as opposed to
                  --  whatever order the set iterator gives us.
                  --  No need for that as long as every iteration over
                  --  a given representative values set yields the same order.
                  --  Not sorting is more efficient, but it makes it harder to
                  --  interpret a Value_Index_Set bit vector when debugging.

                  while Has_Next (Iter) loop
                     Next (Iter, Point (P));

                     --  If we have finished building up a Point value, then
                     --  test it for matching. Otherwise, recurse to continue
                     --  building up a point value.

                     if P = Part_Id'Last then
                        Test_Point_For_Match;
                     else
                        Test_Points (P + 1);
                     end if;
                  end loop;
               end Test_Points;

            begin
               Test_Points (1);
               if (for all Flag of Matches => not Flag) then
                  return Empty;
               end if;
               return Allocate_Table_Element (Matches);
            end Matching_Values;

         end Value_Sets;

         --------------
         -- Analysis --
         --------------

         function Analysis return Choices_Info is
            Result : Choices_Info;
            Alt    : Node_Id := First (Alternatives (Case_Statement));
            A_Id   : Alternative_Id := 1;
            C_Id   : Choice_Id := 1;
         begin
            while Present (Alt) loop
               declare
                  Choice : Node_Id := First (Discrete_Choices (Alt));
               begin
                  while Present (Choice) loop
                     if Nkind (Choice) = N_Others_Choice then
                        pragma Assert (Choices_Bounds (C_Id).Is_Others);
                        Result (C_Id) :=
                          (Alternative => A_Id,
                           Is_Others   => True);
                     else
                        Result (C_Id) :=
                          (Alternative => A_Id,
                           Is_Others   => False,
                           Matches     => Value_Sets.Matching_Values
                                            (Choices_Bounds (C_Id).Ranges));
                     end if;
                     Next (Choice);
                     if C_Id /= Choice_Id'Last then
                        C_Id := C_Id + 1;
                     end if;
                  end loop;
               end;

               Next (Alt);
               if A_Id /= Alternative_Id'Last then
                  A_Id := A_Id + 1;
               end if;
            end loop;

            pragma Assert (A_Id = Alternative_Id'Last);
            pragma Assert (C_Id = Choice_Id'Last);

            return Result;
         end Analysis;

      end Choice_Analysis;

   end Composite_Case_Ops;

   --------------------------
   -- Expand_Others_Choice --
   --------------------------

   procedure Expand_Others_Choice
     (Case_Table    : Choice_Table_Type;
      Others_Choice : Node_Id;
      Choice_Type   : Entity_Id)
   is
      Loc         : constant Source_Ptr := Sloc (Others_Choice);
      Choice_List : constant List_Id    := New_List;
      Choice      : Node_Id;
      Exp_Lo      : Node_Id;
      Exp_Hi      : Node_Id;
      Hi          : Uint;
      Lo          : Uint;
      Previous_Hi : Uint;

      function Build_Choice (Value1, Value2 : Uint) return Node_Id;
      --  Builds a node representing the missing choices given by Value1 and
      --  Value2. A N_Range node is built if there is more than one literal
      --  value missing. Otherwise a single N_Integer_Literal, N_Identifier
      --  or N_Character_Literal is built depending on what Choice_Type is.

      function Lit_Of (Value : Uint) return Node_Id;
      --  Returns the Node_Id for the enumeration literal corresponding to the
      --  position given by Value within the enumeration type Choice_Type. The
      --  returned value has its Is_Static_Expression flag set to true.

      ------------------
      -- Build_Choice --
      ------------------

      function Build_Choice (Value1, Value2 : Uint) return Node_Id is
         Lit_Node : Node_Id;
         Lo, Hi   : Node_Id;

      begin
         --  If there is only one choice value missing between Value1 and
         --  Value2, build an integer or enumeration literal to represent it.

         if Value1 = Value2 then
            if Is_Integer_Type (Choice_Type) then
               Lit_Node := Make_Integer_Literal (Loc, Value1);
               Set_Etype (Lit_Node, Choice_Type);
               Set_Is_Static_Expression (Lit_Node);
            else
               Lit_Node := Lit_Of (Value1);
            end if;

         --  Otherwise is more that one choice value that is missing between
         --  Value1 and Value2, therefore build a N_Range node of either
         --  integer or enumeration literals.

         else
            if Is_Integer_Type (Choice_Type) then
               Lo := Make_Integer_Literal (Loc, Value1);
               Set_Etype (Lo, Choice_Type);
               Set_Is_Static_Expression (Lo);
               Hi := Make_Integer_Literal (Loc, Value2);
               Set_Etype (Hi, Choice_Type);
               Set_Is_Static_Expression (Hi);
               Lit_Node :=
                 Make_Range (Loc,
                   Low_Bound  => Lo,
                   High_Bound => Hi);

            else
               Lit_Node :=
                 Make_Range (Loc,
                   Low_Bound  => Lit_Of (Value1),
                   High_Bound => Lit_Of (Value2));
            end if;
         end if;

         return Lit_Node;
      end Build_Choice;

      ------------
      -- Lit_Of --
      ------------

      function Lit_Of (Value : Uint) return Node_Id is
         Lit : Entity_Id;

      begin
         --  In the case where the literal is of type Character, there needs
         --  to be some special handling since there is no explicit chain
         --  of literals to search. Instead, a N_Character_Literal node
         --  is created with the appropriate Char_Code and Chars fields.

         if Is_Standard_Character_Type (Choice_Type) then
            Set_Character_Literal_Name (UI_To_CC (Value));
            Lit :=
              Make_Character_Literal (Loc,
                Chars              => Name_Find,
                Char_Literal_Value => Value);
            Set_Etype (Lit, Choice_Type);
            Set_Is_Static_Expression (Lit, True);
            return Lit;

         --  Otherwise, iterate through the literals list of Choice_Type
         --  "Value" number of times until the desired literal is reached
         --  and then return an occurrence of it.

         else
            Lit := First_Literal (Choice_Type);
            for J in 1 .. UI_To_Int (Value) loop
               Next_Literal (Lit);
            end loop;

            return New_Occurrence_Of (Lit, Loc);
         end if;
      end Lit_Of;

   --  Start of processing for Expand_Others_Choice

   begin
      if Case_Table'Last = 0 then

         --  Special case: only an others case is present. The others case
         --  covers the full range of the type.

         if Is_OK_Static_Subtype (Choice_Type) then
            Choice := New_Occurrence_Of (Choice_Type, Loc);
         else
            Choice := New_Occurrence_Of (Base_Type (Choice_Type), Loc);
         end if;

         Set_Others_Discrete_Choices (Others_Choice, New_List (Choice));
         return;
      end if;

      --  Establish the bound values for the choice depending upon whether the
      --  type of the case statement is static or not.

      if Is_OK_Static_Subtype (Choice_Type) then
         Exp_Lo := Type_Low_Bound (Choice_Type);
         Exp_Hi := Type_High_Bound (Choice_Type);
      else
         Exp_Lo := Type_Low_Bound (Base_Type (Choice_Type));
         Exp_Hi := Type_High_Bound (Base_Type (Choice_Type));
      end if;

      Lo := Expr_Value (Case_Table (1).Lo);
      Hi := Expr_Value (Case_Table (1).Hi);
      Previous_Hi := Expr_Value (Case_Table (1).Hi);

      --  Build the node for any missing choices that are smaller than any
      --  explicit choices given in the case.

      if Expr_Value (Exp_Lo) < Lo then
         Append (Build_Choice (Expr_Value (Exp_Lo), Lo - 1), Choice_List);
      end if;

      --  Build the nodes representing any missing choices that lie between
      --  the explicit ones given in the case.

      for J in 2 .. Case_Table'Last loop
         Lo := Expr_Value (Case_Table (J).Lo);
         Hi := Expr_Value (Case_Table (J).Hi);

         if Lo /= (Previous_Hi + 1) then
            Append_To (Choice_List, Build_Choice (Previous_Hi + 1, Lo - 1));
         end if;

         Previous_Hi := Hi;
      end loop;

      --  Build the node for any missing choices that are greater than any
      --  explicit choices given in the case.

      if Expr_Value (Exp_Hi) > Hi then
         Append (Build_Choice (Hi + 1, Expr_Value (Exp_Hi)), Choice_List);
      end if;

      Set_Others_Discrete_Choices (Others_Choice, Choice_List);

      --  Warn on null others list if warning option set

      if Warn_On_Redundant_Constructs
        and then Comes_From_Source (Others_Choice)
        and then Is_Empty_List (Choice_List)
      then
         Error_Msg_N ("?r?OTHERS choice is redundant", Others_Choice);
         Error_Msg_N ("\?r?previous choices cover all values", Others_Choice);
      end if;
   end Expand_Others_Choice;

   -----------
   -- No_OP --
   -----------

   procedure No_OP (C : Node_Id) is
   begin
      if Nkind (C) = N_Range and then Warn_On_Redundant_Constructs then
         Error_Msg_N ("choice is an empty range?r?", C);
      end if;
   end No_OP;

   -----------------------------
   -- Generic_Analyze_Choices --
   -----------------------------

   package body Generic_Analyze_Choices is

      --  The following type is used to gather the entries for the choice
      --  table, so that we can then allocate the right length.

      type Link;
      type Link_Ptr is access all Link;

      type Link is record
         Val : Choice_Bounds;
         Nxt : Link_Ptr;
      end record;

      ---------------------
      -- Analyze_Choices --
      ---------------------

      procedure Analyze_Choices
        (Alternatives : List_Id;
         Subtyp       : Entity_Id)
      is
         Choice_Type : constant Entity_Id := Base_Type (Subtyp);
         --  The actual type against which the discrete choices are resolved.
         --  Note that this type is always the base type not the subtype of the
         --  ruling expression, index or discriminant.

         Expected_Type : Entity_Id;
         --  The expected type of each choice. Equal to Choice_Type, except if
         --  the expression is universal, in which case the choices can be of
         --  any integer type.

         Alt : Node_Id;
         --  A case statement alternative or a variant in a record type
         --  declaration.

         Choice : Node_Id;
         Kind   : Node_Kind;
         --  The node kind of the current Choice

      begin
         --  Set Expected type (= choice type except for universal integer,
         --  where we accept any integer type as a choice).

         if Choice_Type = Universal_Integer then
            Expected_Type := Any_Integer;
         else
            Expected_Type := Choice_Type;
         end if;

         --  Now loop through the case alternatives or record variants

         Alt := First (Alternatives);
         while Present (Alt) loop

            --  If pragma, just analyze it

            if Nkind (Alt) = N_Pragma then
               Analyze (Alt);

            --  Otherwise we have an alternative. In most cases the semantic
            --  processing leaves the list of choices unchanged

            --  Check each choice against its base type

            else
               Choice := First (Discrete_Choices (Alt));
               while Present (Choice) loop
                  Analyze (Choice);
                  Kind := Nkind (Choice);

                  --  Choice is a Range

                  if Kind = N_Range
                    or else (Kind = N_Attribute_Reference
                              and then Attribute_Name (Choice) = Name_Range)
                  then
                     Resolve (Choice, Expected_Type);

                  --  Choice is a subtype name, nothing further to do now

                  elsif Is_Entity_Name (Choice)
                    and then Is_Type (Entity (Choice))
                  then
                     null;

                  --  Choice is a subtype indication

                  elsif Kind = N_Subtype_Indication then
                     Resolve_Discrete_Subtype_Indication
                       (Choice, Expected_Type);

                  --  Others choice, no analysis needed

                  elsif Kind = N_Others_Choice then
                     null;

                  --  Only other possibility is an expression

                  else
                     Resolve (Choice, Expected_Type);
                  end if;

                  --  Move to next choice

                  Next (Choice);
               end loop;

               Process_Associated_Node (Alt);
            end if;

            Next (Alt);
         end loop;
      end Analyze_Choices;

   end Generic_Analyze_Choices;

   ---------------------------
   -- Generic_Check_Choices --
   ---------------------------

   package body Generic_Check_Choices is

      --  The following type is used to gather the entries for the choice
      --  table, so that we can then allocate the right length.

      type Link;
      type Link_Ptr is access all Link;

      type Link is record
         Val : Choice_Bounds;
         Nxt : Link_Ptr;
      end record;

      procedure Free is new Ada.Unchecked_Deallocation (Link, Link_Ptr);

      -------------------
      -- Check_Choices --
      -------------------

      procedure Check_Choices
        (N              : Node_Id;
         Alternatives   : List_Id;
         Subtyp         : Entity_Id;
         Others_Present : out Boolean)
      is
         E : Entity_Id;

         Raises_CE : Boolean;
         --  Set True if one of the bounds of a choice raises CE

         Enode : Node_Id;
         --  This is where we post error messages for bounds out of range

         Choice_List : Link_Ptr := null;
         --  Gather list of choices

         Num_Choices : Nat := 0;
         --  Number of entries in Choice_List

         Choice_Type : constant Entity_Id := Base_Type (Subtyp);
         --  The actual type against which the discrete choices are resolved.
         --  Note that this type is always the base type not the subtype of the
         --  ruling expression, index or discriminant.

         Bounds_Type : Entity_Id;
         --  The type from which are derived the bounds of the values covered
         --  by the discrete choices (see 3.8.1 (4)). If a discrete choice
         --  specifies a value outside of these bounds we have an error.

         Bounds_Lo : Uint;
         Bounds_Hi : Uint;
         --  The actual bounds of the above type

         Expected_Type : Entity_Id;
         --  The expected type of each choice. Equal to Choice_Type, except if
         --  the expression is universal, in which case the choices can be of
         --  any integer type.

         Alt : Node_Id;
         --  A case statement alternative or a variant in a record type
         --  declaration.

         Choice : Node_Id;
         Kind   : Node_Kind;
         --  The node kind of the current Choice

         Others_Choice : Node_Id := Empty;
         --  Remember others choice if it is present (empty otherwise)

         procedure Check (Choice : Node_Id; Lo, Hi : Node_Id);
         --  Checks the validity of the bounds of a choice. When the bounds
         --  are static and no error occurred the bounds are collected for
         --  later entry into the choices table so that they can be sorted
         --  later on.

         procedure Check_Case_Pattern_Choices;
         --  Check choices validity for the Ada extension case where the
         --  selecting expression is not of a discrete type and so the
         --  choices are patterns.

         procedure Check_Composite_Case_Selector;
         --  Check that the (non-discrete) type of the expression being
         --  cased on is suitable.

         procedure Handle_Static_Predicate
           (Typ : Entity_Id;
            Lo  : Node_Id;
            Hi  : Node_Id);
         --  If the type of the alternative has predicates, we must examine
         --  each subset of the predicate rather than the bounds of the type
         --  itself. This is relevant when the choice is a subtype mark or a
         --  subtype indication.

         -----------
         -- Check --
         -----------

         procedure Check (Choice : Node_Id; Lo, Hi : Node_Id) is
            Lo_Val : Uint;
            Hi_Val : Uint;

         begin
            --  First check if an error was already detected on either bounds

            if Etype (Lo) = Any_Type or else Etype (Hi) = Any_Type then
               return;

            --  Do not insert non static choices in the table to be sorted

            elsif not Is_OK_Static_Expression (Lo)
                    or else
                  not Is_OK_Static_Expression (Hi)
            then
               Process_Non_Static_Choice (Choice);
               return;

            --  Ignore range which raise constraint error

            elsif Raises_Constraint_Error (Lo)
              or else Raises_Constraint_Error (Hi)
            then
               Raises_CE := True;
               return;

            --  AI05-0188 : Within an instance the non-others choices do not
            --  have to belong to the actual subtype.

            elsif Ada_Version >= Ada_2012 and then In_Instance then
               return;

            --  Otherwise we have an OK static choice

            else
               Lo_Val := Expr_Value (Lo);
               Hi_Val := Expr_Value (Hi);

               --  Do not insert null ranges in the choices table

               if Lo_Val > Hi_Val then
                  Process_Empty_Choice (Choice);
                  return;
               end if;
            end if;

            --  Check for low bound out of range

            if Lo_Val < Bounds_Lo then

               --  If the choice is an entity name, then it is a type, and we
               --  want to post the message on the reference to this entity.
               --  Otherwise post it on the lower bound of the range.

               if Is_Entity_Name (Choice) then
                  Enode := Choice;
               else
                  Enode := Lo;
               end if;

               --  Specialize message for integer/enum type

               if Is_Integer_Type (Bounds_Type) then
                  Error_Msg_Uint_1 := Bounds_Lo;
                  Error_Msg_N ("minimum allowed choice value is^", Enode);
               else
                  Error_Msg_Name_1 := Choice_Image (Bounds_Lo, Bounds_Type);
                  Error_Msg_N ("minimum allowed choice value is%", Enode);
               end if;
            end if;

            --  Check for high bound out of range

            if Hi_Val > Bounds_Hi then

               --  If the choice is an entity name, then it is a type, and we
               --  want to post the message on the reference to this entity.
               --  Otherwise post it on the upper bound of the range.

               if Is_Entity_Name (Choice) then
                  Enode := Choice;
               else
                  Enode := Hi;
               end if;

               --  Specialize message for integer/enum type

               if Is_Integer_Type (Bounds_Type) then
                  Error_Msg_Uint_1 := Bounds_Hi;
                  Error_Msg_N ("maximum allowed choice value is^", Enode);
               else
                  Error_Msg_Name_1 := Choice_Image (Bounds_Hi, Bounds_Type);
                  Error_Msg_N ("maximum allowed choice value is%", Enode);
               end if;
            end if;

            --  Collect bounds in the list

            --  Note: we still store the bounds, even if they are out of range,
            --  since this may prevent unnecessary cascaded errors for values
            --  that are covered by such an excessive range.

            Choice_List :=
              new Link'(Val => (Lo, Hi, Choice), Nxt => Choice_List);
            Num_Choices := Num_Choices + 1;
         end Check;

         --------------------------------
         -- Check_Case_Pattern_Choices --
         --------------------------------

         procedure Check_Case_Pattern_Choices is
            package Ops is new Composite_Case_Ops.Choice_Analysis
              (Case_Statement => N);
            use Ops;
            use Ops.Value_Sets;

            Empty : Value_Set renames Value_Sets.Empty;
            --  Cope with hiding due to multiple use clauses

            Info        : constant Choices_Info := Analysis;
            Others_Seen : Boolean := False;

         begin
            declare
               Matches : array (Alternative_Id) of Value_Sets.Value_Set :=
                 (others => Empty);

               Flag_Overlapping_Within_One_Alternative : constant Boolean :=
                 False;
               --  We may want to flag overlapping (perhaps with only a
               --  warning) if the pattern binds an identifier, as in
               --    when (Positive, <X>) | (Integer, <X>) =>

               Covered : Value_Set := Empty;
               --  The union of all alternatives seen so far
            begin
               if Composite_Case_Ops.Simplified_Composite_Coverage_Rules then
                  if not (for some Choice of Info => Choice.Is_Others) then
                     Error_Msg_N ("others choice required", N);
                  end if;
                  return;
               end if;

               for Choice of Info loop
                  if Choice.Is_Others then
                     Others_Seen := True;
                  else
                     if Flag_Overlapping_Within_One_Alternative
                        and then (Compare (Matches (Choice.Alternative),
                                  Choice.Matches) /= Disjoint)
                     then
                        Error_Msg_N
                          ("bad overlapping within one alternative", N);
                     end if;

                     Union (Target => Matches (Choice.Alternative),
                            Source => Choice.Matches);
                  end if;
               end loop;

               for A1 in Alternative_Id loop
                  for A2 in Alternative_Id
                              range A1 + 1 .. Alternative_Id'Last
                  loop
                     case Compare (Matches (A1), Matches (A2)) is
                        when Disjoint | Contained_By =>
                           null; -- OK
                        when Overlaps =>
                           declare
                              Uncovered_1, Uncovered_2 : Value_Set := Empty;
                           begin
                              Union (Uncovered_1, Matches (A1));
                              Remove (Uncovered_1, Covered);
                              Union (Uncovered_2, Matches (A2));
                              Remove (Uncovered_2, Covered);

                              --  Recheck for overlap after removing choices
                              --  covered by earlier alternatives.

                              case Compare (Uncovered_1, Uncovered_2) is
                                 when Disjoint | Contained_By =>
                                    null;
                                 when Contains | Overlaps | Equal =>
                                    Error_Msg_N
                                      ("bad alternative overlapping", N);
                              end case;
                           end;

                        when Equal =>
                           Error_Msg_N ("alternatives match same values", N);
                        when Contains =>
                           Error_Msg_N ("alternatives in wrong order", N);
                     end case;
                  end loop;

                  Union (Target => Covered, Source => Matches (A1));
               end loop;

               if (not Others_Seen) and then not Complement_Is_Empty (Covered)
               then
                  Error_Msg_N ("not all values are covered", N);
               end if;
            end;

            Ops.Value_Sets.Free_Value_Sets;
         end Check_Case_Pattern_Choices;

         -----------------------------------
         -- Check_Composite_Case_Selector --
         -----------------------------------

         procedure Check_Composite_Case_Selector is
         begin
            if not Is_Composite_Type (Subtyp) then
               Error_Msg_N
                 ("case selector type must be discrete or composite", N);
            elsif Is_Limited_Type (Subtyp) then
               Error_Msg_N ("case selector type must not be limited", N);
            elsif Is_Class_Wide_Type (Subtyp) then
               Error_Msg_N ("case selector type must not be class-wide", N);
            elsif Needs_Finalization (Subtyp)
              and then Is_Newly_Constructed
                         (Expression (N), Context_Requires_NC => False)
            then
               --  We could allow this case as long as there are no bindings.
               --
               --  If there are bindings, then allowing this case will get
               --  messy because the selector expression will be finalized
               --  before the statements of the selected alternative are
               --  executed (unless we add an INOX-specific change to the
               --  accessibility rules to prevent this earlier-than-wanted
               --  finalization, but adding new INOX-specific accessibility
               --  complexity is probably not the direction we want to go).
               --  This early selector finalization would be ok if we made
               --  copies in this case (so that the bindings would not yield
               --  a view of a finalized object), but then we'd have to deal
               --  with finalizing those copies (which would necessarily
               --  include defining their accessibility level). So it gets
               --  messy either way.

               Error_Msg_N ("case selector must not require finalization", N);
            end if;
         end Check_Composite_Case_Selector;

         -----------------------------
         -- Handle_Static_Predicate --
         -----------------------------

         procedure Handle_Static_Predicate
           (Typ : Entity_Id;
            Lo  : Node_Id;
            Hi  : Node_Id)
         is
            P : Node_Id;
            C : Node_Id;

         begin
            --  Loop through entries in predicate list, checking each entry.
            --  Note that if the list is empty, corresponding to a False
            --  predicate, then no choices are checked. If the choice comes
            --  from a subtype indication, the given range may have bounds
            --  that narrow the predicate choices themselves, so we must
            --  consider only those entries within the range of the given
            --  subtype indication..

            P := First (Static_Discrete_Predicate (Typ));
            while Present (P) loop

               --  Check that part of the predicate choice is included in the
               --  given bounds.

               if Expr_Value (High_Bound (P)) >= Expr_Value (Lo)
                 and then Expr_Value (Low_Bound (P)) <= Expr_Value (Hi)
               then
                  C := New_Copy (P);
                  Set_Sloc (C, Sloc (Choice));
                  Set_Original_Node (C, Choice);

                  if Expr_Value (Low_Bound (C)) < Expr_Value (Lo) then
                     Set_Low_Bound (C, Lo);
                  end if;

                  if Expr_Value (High_Bound (C)) > Expr_Value (Hi) then
                     Set_High_Bound (C, Hi);
                  end if;

                  Check (C, Low_Bound (C), High_Bound (C));
               end if;

               Next (P);
            end loop;

            Set_Has_SP_Choice (Alt);
         end Handle_Static_Predicate;

      --  Start of processing for Check_Choices

      begin
         Raises_CE      := False;
         Others_Present := False;

         --  If Subtyp is not a discrete type or there was some other error,
         --  then don't try any semantic checking on the choices since we have
         --  a complete mess.

         if not Is_Discrete_Type (Subtyp) or else Subtyp = Any_Type then

            --  Hold on, maybe it isn't a complete mess after all.

            if Extensions_Allowed and then Subtyp /= Any_Type then
               Check_Composite_Case_Selector;
               Check_Case_Pattern_Choices;
            end if;

            return;
         end if;

         --  If Subtyp is not a static subtype Ada 95 requires then we use the
         --  bounds of its base type to determine the values covered by the
         --  discrete choices.

         --  In Ada 2012, if the subtype has a nonstatic predicate the full
         --  range of the base type must be covered as well.

         if Is_OK_Static_Subtype (Subtyp) then
            if not Has_Predicates (Subtyp)
              or else Has_Static_Predicate (Subtyp)
            then
               Bounds_Type := Subtyp;
            else
               Bounds_Type := Choice_Type;
            end if;

         else
            Bounds_Type := Choice_Type;
         end if;

         --  Obtain static bounds of type, unless this is a generic formal
         --  discrete type for which all choices will be nonstatic.

         if not Is_Generic_Type (Root_Type (Bounds_Type))
           or else Ekind (Bounds_Type) /= E_Enumeration_Type
         then
            Bounds_Lo := Expr_Value (Type_Low_Bound (Bounds_Type));
            Bounds_Hi := Expr_Value (Type_High_Bound (Bounds_Type));
         end if;

         if Choice_Type = Universal_Integer then
            Expected_Type := Any_Integer;
         else
            Expected_Type := Choice_Type;
         end if;

         --  Now loop through the case alternatives or record variants

         Alt := First (Alternatives);
         while Present (Alt) loop

            --  If pragma, just analyze it

            if Nkind (Alt) = N_Pragma then
               Analyze (Alt);

            --  Otherwise we have an alternative. In most cases the semantic
            --  processing leaves the list of choices unchanged

            --  Check each choice against its base type

            else
               Choice := First (Discrete_Choices (Alt));
               while Present (Choice) loop
                  Kind := Nkind (Choice);

                  --  Choice is a Range

                  if Kind = N_Range
                    or else (Kind = N_Attribute_Reference
                              and then Attribute_Name (Choice) = Name_Range)
                  then
                     Check (Choice, Low_Bound (Choice), High_Bound (Choice));

                  --  Choice is a subtype name

                  elsif Is_Entity_Name (Choice)
                    and then Is_Type (Entity (Choice))
                  then
                     --  Check for inappropriate type

                     if not Covers (Expected_Type, Etype (Choice)) then
                        Wrong_Type (Choice, Choice_Type);

                     --  Type is OK, so check further

                     else
                        E := Entity (Choice);

                        --  Case of predicated subtype

                        if Has_Predicates (E) then

                           --  Use of nonstatic predicate is an error

                           if not Is_Discrete_Type (E)
                             or else not Has_Static_Predicate (E)
                             or else Has_Dynamic_Predicate_Aspect (E)
                           then
                              Bad_Predicated_Subtype_Use
                                ("cannot use subtype& with non-static "
                                 & "predicate as case alternative",
                                 Choice, E, Suggest_Static => True);

                           --  Static predicate case. The bounds are those of
                           --  the given subtype.

                           else
                              Handle_Static_Predicate (E,
                                Type_Low_Bound (E), Type_High_Bound (E));
                           end if;

                        --  Not predicated subtype case

                        elsif not Is_OK_Static_Subtype (E) then
                           Process_Non_Static_Choice (Choice);
                        else
                           Check
                             (Choice, Type_Low_Bound (E), Type_High_Bound (E));
                        end if;
                     end if;

                  --  Choice is a subtype indication

                  elsif Kind = N_Subtype_Indication then
                     Resolve_Discrete_Subtype_Indication
                       (Choice, Expected_Type);

                     if Etype (Choice) /= Any_Type then
                        declare
                           C : constant Node_Id := Constraint (Choice);
                           R : constant Node_Id := Range_Expression (C);
                           L : constant Node_Id := Low_Bound (R);
                           H : constant Node_Id := High_Bound (R);

                        begin
                           E := Entity (Subtype_Mark (Choice));

                           if not Is_OK_Static_Subtype (E) then
                              Process_Non_Static_Choice (Choice);

                           else
                              if Is_OK_Static_Expression (L)
                                   and then
                                 Is_OK_Static_Expression (H)
                              then
                                 if Expr_Value (L) > Expr_Value (H) then
                                    Process_Empty_Choice (Choice);
                                 else
                                    if Is_Out_Of_Range (L, E) then
                                       Apply_Compile_Time_Constraint_Error
                                         (L, "static value out of range",
                                          CE_Range_Check_Failed);
                                    end if;

                                    if Is_Out_Of_Range (H, E) then
                                       Apply_Compile_Time_Constraint_Error
                                         (H, "static value out of range",
                                          CE_Range_Check_Failed);
                                    end if;
                                 end if;
                              end if;

                              --  Check applicable predicate values within the
                              --  bounds of the given range.

                              if Has_Static_Predicate (E) then
                                 Handle_Static_Predicate (E, L, H);

                              else
                                 Check (Choice, L, H);
                              end if;
                           end if;
                        end;
                     end if;

                  --  The others choice is only allowed for the last
                  --  alternative and as its only choice.

                  elsif Kind = N_Others_Choice then
                     if not (Choice = First (Discrete_Choices (Alt))
                              and then Choice = Last (Discrete_Choices (Alt))
                              and then Alt = Last (Alternatives))
                     then
                        Error_Msg_N
                          ("the choice OTHERS must appear alone and last",
                           Choice);
                        return;
                     end if;

                     Others_Present := True;
                     Others_Choice  := Choice;

                  --  Only other possibility is an expression

                  else
                     Check (Choice, Choice, Choice);
                  end if;

                  --  Move to next choice

                  Next (Choice);
               end loop;

               Process_Associated_Node (Alt);
            end if;

            Next (Alt);
         end loop;

         --  Now we can create the Choice_Table, since we know how long
         --  it needs to be so we can allocate exactly the right length.

         declare
            Choice_Table : Choice_Table_Type (0 .. Num_Choices);

         begin
            --  Now copy the items we collected in the linked list into this
            --  newly allocated table (leave entry 0 unused for sorting).

            declare
               T : Link_Ptr;
            begin
               for J in 1 .. Num_Choices loop
                  T := Choice_List;
                  Choice_List := T.Nxt;
                  Choice_Table (J) := T.Val;
                  Free (T);
               end loop;
            end;

            Check_Choice_Set
              (Choice_Table,
               Bounds_Type,
               Subtyp,
               Others_Present or else (Choice_Type = Universal_Integer),
               N);

            --  If no others choice we are all done, otherwise we have one more
            --  step, which is to set the Others_Discrete_Choices field of the
            --  others choice (to contain all otherwise unspecified choices).
            --  Skip this if CE is known to be raised.

            if Others_Present and not Raises_CE then
               Expand_Others_Choice
                 (Case_Table    => Choice_Table,
                  Others_Choice => Others_Choice,
                  Choice_Type   => Bounds_Type);
            end if;
         end;
      end Check_Choices;

   end Generic_Check_Choices;

   -----------------------------------------
   --  Has_Static_Discriminant_Constraint --
   -----------------------------------------

   function Has_Static_Discriminant_Constraint
     (Subtyp : Entity_Id) return Boolean
   is
   begin
      if Has_Discriminants (Subtyp) and then Is_Constrained (Subtyp) then
         declare
            DC_Elmt : Elmt_Id := First_Elmt (Discriminant_Constraint (Subtyp));
         begin
            while Present (DC_Elmt) loop
               if not All_Composite_Constraints_Static (Node (DC_Elmt)) then
                  return False;
               end if;
               Next_Elmt (DC_Elmt);
            end loop;
            return True;
         end;
      end if;
      return False;
   end Has_Static_Discriminant_Constraint;

   ----------------------------
   -- Is_Case_Choice_Pattern --
   ----------------------------

   function Is_Case_Choice_Pattern (Expr : Node_Id) return Boolean is
      E : Node_Id := Expr;
   begin
      if not Extensions_Allowed then
         return False;
      end if;

      loop
         case Nkind (E) is
            when N_Case_Statement_Alternative
               | N_Case_Expression_Alternative
            =>
               --  We could return False if selecting expression is discrete,
               --  but this doesn't seem to be worth the bother.
               return True;

            when N_Empty
               | N_Statement_Other_Than_Procedure_Call
               | N_Procedure_Call_Statement
               | N_Declaration
            =>
               return False;

            when others =>
               E := Parent (E);
         end case;
      end loop;
   end Is_Case_Choice_Pattern;

end Sem_Case;
