------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                               C H E C K S                                --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2021, 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 Debug;          use Debug;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Elists;         use Elists;
with Eval_Fat;       use Eval_Fat;
with Exp_Ch11;       use Exp_Ch11;
with Exp_Ch4;        use Exp_Ch4;
with Exp_Pakd;       use Exp_Pakd;
with Exp_Util;       use Exp_Util;
with Expander;       use Expander;
with Freeze;         use Freeze;
with Lib;            use Lib;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Opt;            use Opt;
with Output;         use Output;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Ch3;        use Sem_Ch3;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Cat;        use Sem_Cat;
with Sem_Disp;       use Sem_Disp;
with Sem_Eval;       use Sem_Eval;
with Sem_Mech;       use Sem_Mech;
with Sem_Res;        use Sem_Res;
with Sem_Util;       use Sem_Util;
with Sem_Warn;       use Sem_Warn;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinput;         use Sinput;
with Snames;         use Snames;
with Sprint;         use Sprint;
with Stand;          use Stand;
with Stringt;        use Stringt;
with Targparm;       use Targparm;
with Tbuild;         use Tbuild;
with Ttypes;         use Ttypes;
with Validsw;        use Validsw;

package body Checks is

   --  General note: many of these routines are concerned with generating
   --  checking code to make sure that constraint error is raised at runtime.
   --  Clearly this code is only needed if the expander is active, since
   --  otherwise we will not be generating code or going into the runtime
   --  execution anyway.

   --  We therefore disconnect most of these checks if the expander is
   --  inactive. This has the additional benefit that we do not need to
   --  worry about the tree being messed up by previous errors (since errors
   --  turn off expansion anyway).

   --  There are a few exceptions to the above rule. For instance routines
   --  such as Apply_Scalar_Range_Check that do not insert any code can be
   --  safely called even when the Expander is inactive (but Errors_Detected
   --  is 0). The benefit of executing this code when expansion is off, is
   --  the ability to emit constraint error warnings for static expressions
   --  even when we are not generating code.

   --  The above is modified in gnatprove mode to ensure that proper check
   --  flags are always placed, even if expansion is off.

   -------------------------------------
   -- Suppression of Redundant Checks --
   -------------------------------------

   --  This unit implements a limited circuit for removal of redundant
   --  checks. The processing is based on a tracing of simple sequential
   --  flow. For any sequence of statements, we save expressions that are
   --  marked to be checked, and then if the same expression appears later
   --  with the same check, then under certain circumstances, the second
   --  check can be suppressed.

   --  Basically, we can suppress the check if we know for certain that
   --  the previous expression has been elaborated (together with its
   --  check), and we know that the exception frame is the same, and that
   --  nothing has happened to change the result of the exception.

   --  Let us examine each of these three conditions in turn to describe
   --  how we ensure that this condition is met.

   --  First, we need to know for certain that the previous expression has
   --  been executed. This is done principally by the mechanism of calling
   --  Conditional_Statements_Begin at the start of any statement sequence
   --  and Conditional_Statements_End at the end. The End call causes all
   --  checks remembered since the Begin call to be discarded. This does
   --  miss a few cases, notably the case of a nested BEGIN-END block with
   --  no exception handlers. But the important thing is to be conservative.
   --  The other protection is that all checks are discarded if a label
   --  is encountered, since then the assumption of sequential execution
   --  is violated, and we don't know enough about the flow.

   --  Second, we need to know that the exception frame is the same. We
   --  do this by killing all remembered checks when we enter a new frame.
   --  Again, that's over-conservative, but generally the cases we can help
   --  with are pretty local anyway (like the body of a loop for example).

   --  Third, we must be sure to forget any checks which are no longer valid.
   --  This is done by two mechanisms, first the Kill_Checks_Variable call is
   --  used to note any changes to local variables. We only attempt to deal
   --  with checks involving local variables, so we do not need to worry
   --  about global variables. Second, a call to any non-global procedure
   --  causes us to abandon all stored checks, since such a all may affect
   --  the values of any local variables.

   --  The following define the data structures used to deal with remembering
   --  checks so that redundant checks can be eliminated as described above.

   --  Right now, the only expressions that we deal with are of the form of
   --  simple local objects (either declared locally, or IN parameters) or
   --  such objects plus/minus a compile time known constant. We can do
   --  more later on if it seems worthwhile, but this catches many simple
   --  cases in practice.

   --  The following record type reflects a single saved check. An entry
   --  is made in the stack of saved checks if and only if the expression
   --  has been elaborated with the indicated checks.

   type Saved_Check is record
      Killed : Boolean;
      --  Set True if entry is killed by Kill_Checks

      Entity : Entity_Id;
      --  The entity involved in the expression that is checked

      Offset : Uint;
      --  A compile time value indicating the result of adding or
      --  subtracting a compile time value. This value is to be
      --  added to the value of the Entity. A value of zero is
      --  used for the case of a simple entity reference.

      Check_Type : Character;
      --  This is set to 'R' for a range check (in which case Target_Type
      --  is set to the target type for the range check) or to 'O' for an
      --  overflow check (in which case Target_Type is set to Empty).

      Target_Type : Entity_Id;
      --  Used only if Do_Range_Check is set. Records the target type for
      --  the check. We need this, because a check is a duplicate only if
      --  it has the same target type (or more accurately one with a
      --  range that is smaller or equal to the stored target type of a
      --  saved check).
   end record;

   --  The following table keeps track of saved checks. Rather than use an
   --  extensible table, we just use a table of fixed size, and we discard
   --  any saved checks that do not fit. That's very unlikely to happen and
   --  this is only an optimization in any case.

   Saved_Checks : array (Int range 1 .. 200) of Saved_Check;
   --  Array of saved checks

   Num_Saved_Checks : Nat := 0;
   --  Number of saved checks

   --  The following stack keeps track of statement ranges. It is treated
   --  as a stack. When Conditional_Statements_Begin is called, an entry
   --  is pushed onto this stack containing the value of Num_Saved_Checks
   --  at the time of the call. Then when Conditional_Statements_End is
   --  called, this value is popped off and used to reset Num_Saved_Checks.

   --  Note: again, this is a fixed length stack with a size that should
   --  always be fine. If the value of the stack pointer goes above the
   --  limit, then we just forget all saved checks.

   Saved_Checks_Stack : array (Int range 1 .. 100) of Nat;
   Saved_Checks_TOS : Nat := 0;

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

   procedure Apply_Arithmetic_Overflow_Strict (N : Node_Id);
   --  Used to apply arithmetic overflow checks for all cases except operators
   --  on signed arithmetic types in MINIMIZED/ELIMINATED case (for which we
   --  call Apply_Arithmetic_Overflow_Minimized_Eliminated below). N can be a
   --  signed integer arithmetic operator (but not an if or case expression).
   --  It is also called for types other than signed integers.

   procedure Apply_Arithmetic_Overflow_Minimized_Eliminated (Op : Node_Id);
   --  Used to apply arithmetic overflow checks for the case where the overflow
   --  checking mode is MINIMIZED or ELIMINATED and we have a signed integer
   --  arithmetic op (which includes the case of if and case expressions). Note
   --  that Do_Overflow_Check may or may not be set for node Op. In these modes
   --  we have work to do even if overflow checking is suppressed.

   procedure Apply_Division_Check
     (N   : Node_Id;
      Rlo : Uint;
      Rhi : Uint;
      ROK : Boolean);
   --  N is an N_Op_Div, N_Op_Rem, or N_Op_Mod node. This routine applies
   --  division checks as required if the Do_Division_Check flag is set.
   --  Rlo and Rhi give the possible range of the right operand, these values
   --  can be referenced and trusted only if ROK is set True.

   procedure Apply_Float_Conversion_Check
     (Expr       : Node_Id;
      Target_Typ : Entity_Id);
   --  The checks on a conversion from a floating-point type to an integer
   --  type are delicate. They have to be performed before conversion, they
   --  have to raise an exception when the operand is a NaN, and rounding must
   --  be taken into account to determine the safe bounds of the operand.

   procedure Apply_Selected_Length_Checks
     (Expr       : Node_Id;
      Target_Typ : Entity_Id;
      Source_Typ : Entity_Id;
      Do_Static  : Boolean);
   --  This is the subprogram that does all the work for Apply_Length_Check
   --  and Apply_Static_Length_Check. Expr, Target_Typ and Source_Typ are as
   --  described for the above routines. The Do_Static flag indicates that
   --  only a static check is to be done.

   procedure Compute_Range_For_Arithmetic_Op
     (Op       : Node_Kind;
      Lo_Left  : Uint;
      Hi_Left  : Uint;
      Lo_Right : Uint;
      Hi_Right : Uint;
      OK       : out Boolean;
      Lo       : out Uint;
      Hi       : out Uint);
   --  Given an integer arithmetical operation Op and the range of values of
   --  its operand(s), try to compute a conservative estimate of the possible
   --  range of values for the result of the operation. Thus if OK is True on
   --  return, the result is known to lie in the range Lo .. Hi (inclusive).
   --  If OK is false, both Lo and Hi are set to No_Uint.

   type Check_Type is new Check_Id range Access_Check .. Division_Check;
   function Check_Needed (Nod : Node_Id; Check : Check_Type) return Boolean;
   --  This function is used to see if an access or division by zero check is
   --  needed. The check is to be applied to a single variable appearing in the
   --  source, and N is the node for the reference. If N is not of this form,
   --  True is returned with no further processing. If N is of the right form,
   --  then further processing determines if the given Check is needed.
   --
   --  The particular circuit is to see if we have the case of a check that is
   --  not needed because it appears in the right operand of a short circuited
   --  conditional where the left operand guards the check. For example:
   --
   --    if Var = 0 or else Q / Var > 12 then
   --       ...
   --    end if;
   --
   --  In this example, the division check is not required. At the same time
   --  we can issue warnings for suspicious use of non-short-circuited forms,
   --  such as:
   --
   --    if Var = 0 or Q / Var > 12 then
   --       ...
   --    end if;

   procedure Find_Check
     (Expr        : Node_Id;
      Check_Type  : Character;
      Target_Type : Entity_Id;
      Entry_OK    : out Boolean;
      Check_Num   : out Nat;
      Ent         : out Entity_Id;
      Ofs         : out Uint);
   --  This routine is used by Enable_Range_Check and Enable_Overflow_Check
   --  to see if a check is of the form for optimization, and if so, to see
   --  if it has already been performed. Expr is the expression to check,
   --  and Check_Type is 'R' for a range check, 'O' for an overflow check.
   --  Target_Type is the target type for a range check, and Empty for an
   --  overflow check. If the entry is not of the form for optimization,
   --  then Entry_OK is set to False, and the remaining out parameters
   --  are undefined. If the entry is OK, then Ent/Ofs are set to the
   --  entity and offset from the expression. Check_Num is the number of
   --  a matching saved entry in Saved_Checks, or zero if no such entry
   --  is located.

   function Get_Discriminal (E : Entity_Id; Bound : Node_Id) return Node_Id;
   --  If a discriminal is used in constraining a prival, Return reference
   --  to the discriminal of the protected body (which renames the parameter
   --  of the enclosing protected operation). This clumsy transformation is
   --  needed because privals are created too late and their actual subtypes
   --  are not available when analysing the bodies of the protected operations.
   --  This function is called whenever the bound is an entity and the scope
   --  indicates a protected operation. If the bound is an in-parameter of
   --  a protected operation that is not a prival, the function returns the
   --  bound itself.
   --  To be cleaned up???

   function Guard_Access
     (Cond : Node_Id;
      Loc  : Source_Ptr;
      Expr : Node_Id) return Node_Id;
   --  In the access type case, guard the test with a test to ensure
   --  that the access value is non-null, since the checks do not
   --  not apply to null access values.

   procedure Install_Static_Check (R_Cno : Node_Id; Loc : Source_Ptr);
   --  Called by Apply_{Length,Range}_Checks to rewrite the tree with the
   --  Constraint_Error node.

   function Is_Signed_Integer_Arithmetic_Op (N : Node_Id) return Boolean;
   --  Returns True if node N is for an arithmetic operation with signed
   --  integer operands. This includes unary and binary operators, and also
   --  if and case expression nodes where the dependent expressions are of
   --  a signed integer type. These are the kinds of nodes for which special
   --  handling applies in MINIMIZED or ELIMINATED overflow checking mode.

   function Range_Or_Validity_Checks_Suppressed
     (Expr : Node_Id) return Boolean;
   --  Returns True if either range or validity checks or both are suppressed
   --  for the type of the given expression, or, if the expression is the name
   --  of an entity, if these checks are suppressed for the entity.

   function Selected_Length_Checks
     (Expr       : Node_Id;
      Target_Typ : Entity_Id;
      Source_Typ : Entity_Id;
      Warn_Node  : Node_Id) return Check_Result;
   --  Like Apply_Selected_Length_Checks, except it doesn't modify
   --  anything, just returns a list of nodes as described in the spec of
   --  this package for the Range_Check function.
   --  ??? In fact it does construct the test and insert it into the tree,
   --  and insert actions in various ways (calling Insert_Action directly
   --  in particular) so we do not call it in GNATprove mode, contrary to
   --  Selected_Range_Checks.

   function Selected_Range_Checks
     (Expr       : Node_Id;
      Target_Typ : Entity_Id;
      Source_Typ : Entity_Id;
      Warn_Node  : Node_Id) return Check_Result;
   --  Like Apply_Range_Check, except it does not modify anything, just
   --  returns a list of nodes as described in the spec of this package
   --  for the Range_Check function.

   ------------------------------
   -- Access_Checks_Suppressed --
   ------------------------------

   function Access_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E) and then Checks_May_Be_Suppressed (E) then
         return Is_Check_Suppressed (E, Access_Check);
      else
         return Scope_Suppress.Suppress (Access_Check);
      end if;
   end Access_Checks_Suppressed;

   -------------------------------------
   -- Accessibility_Checks_Suppressed --
   -------------------------------------

   function Accessibility_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if No_Dynamic_Accessibility_Checks_Enabled (E) then
         return True;

      elsif Present (E) and then Checks_May_Be_Suppressed (E) then
         return Is_Check_Suppressed (E, Accessibility_Check);

      else
         return Scope_Suppress.Suppress (Accessibility_Check);
      end if;
   end Accessibility_Checks_Suppressed;

   -----------------------------
   -- Activate_Division_Check --
   -----------------------------

   procedure Activate_Division_Check (N : Node_Id) is
   begin
      Set_Do_Division_Check (N, True);
      Possible_Local_Raise (N, Standard_Constraint_Error);
   end Activate_Division_Check;

   -----------------------------
   -- Activate_Overflow_Check --
   -----------------------------

   procedure Activate_Overflow_Check (N : Node_Id) is
      Typ : constant Entity_Id := Etype (N);

   begin
      --  Floating-point case. If Etype is not set (this can happen when we
      --  activate a check on a node that has not yet been analyzed), then
      --  we assume we do not have a floating-point type (as per our spec).

      if Present (Typ) and then Is_Floating_Point_Type (Typ) then

         --  Ignore call if we have no automatic overflow checks on the target
         --  and Check_Float_Overflow mode is not set. These are the cases in
         --  which we expect to generate infinities and NaN's with no check.

         if not (Machine_Overflows_On_Target or Check_Float_Overflow) then
            return;

         --  Ignore for unary operations ("+", "-", abs) since these can never
         --  result in overflow for floating-point cases.

         elsif Nkind (N) in N_Unary_Op then
            return;

         --  Otherwise we will set the flag

         else
            null;
         end if;

      --  Discrete case

      else
         --  Nothing to do for Rem/Mod/Plus (overflow not possible, the check
         --  for zero-divide is a divide check, not an overflow check).

         if Nkind (N) in N_Op_Rem | N_Op_Mod | N_Op_Plus then
            return;
         end if;
      end if;

      --  Fall through for cases where we do set the flag

      Set_Do_Overflow_Check (N);
      Possible_Local_Raise (N, Standard_Constraint_Error);
   end Activate_Overflow_Check;

   --------------------------
   -- Activate_Range_Check --
   --------------------------

   procedure Activate_Range_Check (N : Node_Id) is
   begin
      Set_Do_Range_Check (N);
      Possible_Local_Raise (N, Standard_Constraint_Error);
   end Activate_Range_Check;

   ---------------------------------
   -- Alignment_Checks_Suppressed --
   ---------------------------------

   function Alignment_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E) and then Checks_May_Be_Suppressed (E) then
         return Is_Check_Suppressed (E, Alignment_Check);
      else
         return Scope_Suppress.Suppress (Alignment_Check);
      end if;
   end Alignment_Checks_Suppressed;

   ----------------------------------
   -- Allocation_Checks_Suppressed --
   ----------------------------------

   --  Note: at the current time there are no calls to this function, because
   --  the relevant check is in the run-time, so it is not a check that the
   --  compiler can suppress anyway, but we still have to recognize the check
   --  name Allocation_Check since it is part of the standard.

   function Allocation_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E) and then Checks_May_Be_Suppressed (E) then
         return Is_Check_Suppressed (E, Allocation_Check);
      else
         return Scope_Suppress.Suppress (Allocation_Check);
      end if;
   end Allocation_Checks_Suppressed;

   -------------------------
   -- Append_Range_Checks --
   -------------------------

   procedure Append_Range_Checks
     (Checks       : Check_Result;
      Stmts        : List_Id;
      Suppress_Typ : Entity_Id;
      Static_Sloc  : Source_Ptr)
   is
      Checks_On : constant Boolean :=
                    not Index_Checks_Suppressed (Suppress_Typ)
                      or else
                    not Range_Checks_Suppressed (Suppress_Typ);

   begin
      --  For now we just return if Checks_On is false, however this could be
      --  enhanced to check for an always True value in the condition and to
      --  generate a compilation warning.

      if not Checks_On then
         return;
      end if;

      for J in 1 .. 2 loop
         exit when No (Checks (J));

         if Nkind (Checks (J)) = N_Raise_Constraint_Error
           and then Present (Condition (Checks (J)))
         then
            Append_To (Stmts, Checks (J));
         else
            Append_To
              (Stmts,
                Make_Raise_Constraint_Error (Static_Sloc,
                  Reason => CE_Range_Check_Failed));
         end if;
      end loop;
   end Append_Range_Checks;

   ------------------------
   -- Apply_Access_Check --
   ------------------------

   procedure Apply_Access_Check (N : Node_Id) is
      P : constant Node_Id := Prefix (N);

   begin
      --  We do not need checks if we are not generating code (i.e. the
      --  expander is not active). This is not just an optimization, there
      --  are cases (e.g. with pragma Debug) where generating the checks
      --  can cause real trouble.

      if not Expander_Active then
         return;
      end if;

      --  No check if short circuiting makes check unnecessary

      if not Check_Needed (P, Access_Check) then
         return;
      end if;

      --  No check if accessing the Offset_To_Top component of a dispatch
      --  table. They are safe by construction.

      if Tagged_Type_Expansion
        and then Present (Etype (P))
        and then Is_RTE (Etype (P), RE_Offset_To_Top_Ptr)
      then
         return;
      end if;

      --  Otherwise go ahead and install the check

      Install_Null_Excluding_Check (P);
   end Apply_Access_Check;

   -------------------------------
   -- Apply_Accessibility_Check --
   -------------------------------

   procedure Apply_Accessibility_Check
     (N           : Node_Id;
      Typ         : Entity_Id;
      Insert_Node : Node_Id)
   is
      Loc : constant Source_Ptr := Sloc (N);

      Check_Cond  : Node_Id;
      Param_Ent   : Entity_Id := Param_Entity (N);
      Param_Level : Node_Id;
      Type_Level  : Node_Id;

   begin
      --  Verify we haven't tried to add a dynamic accessibility check when we
      --  shouldn't.

      pragma Assert (not No_Dynamic_Accessibility_Checks_Enabled (N));

      if Ada_Version >= Ada_2012
         and then not Present (Param_Ent)
         and then Is_Entity_Name (N)
         and then Ekind (Entity (N)) in E_Constant | E_Variable
         and then Present (Effective_Extra_Accessibility (Entity (N)))
      then
         Param_Ent := Entity (N);
         while Present (Renamed_Object (Param_Ent)) loop
            --  Renamed_Object must return an Entity_Name here
            --  because of preceding "Present (E_E_A (...))" test.

            Param_Ent := Entity (Renamed_Object (Param_Ent));
         end loop;
      end if;

      if Inside_A_Generic then
         return;

      --  Only apply the run-time check if the access parameter has an
      --  associated extra access level parameter and when accessibility checks
      --  are enabled.

      elsif Present (Param_Ent)
         and then Present (Get_Dynamic_Accessibility (Param_Ent))
         and then not Accessibility_Checks_Suppressed (Param_Ent)
         and then not Accessibility_Checks_Suppressed (Typ)
      then
         --  Obtain the parameter's accessibility level

         Param_Level :=
           New_Occurrence_Of (Get_Dynamic_Accessibility (Param_Ent), Loc);

         --  Use the dynamic accessibility parameter for the function's result
         --  when one has been created instead of statically referring to the
         --  deepest type level so as to appropriatly handle the rules for
         --  RM 3.10.2 (10.1/3).

         if Ekind (Scope (Param_Ent)) = E_Function
           and then In_Return_Value (N)
           and then Ekind (Typ) = E_Anonymous_Access_Type
         then
            --  Associate the level of the result type to the extra result
            --  accessibility parameter belonging to the current function.

            if Present (Extra_Accessibility_Of_Result (Scope (Param_Ent))) then
               Type_Level :=
                 New_Occurrence_Of
                   (Extra_Accessibility_Of_Result (Scope (Param_Ent)), Loc);

            --  In Ada 2005 and earlier modes, a result extra accessibility
            --  parameter is not generated and no dynamic check is performed.

            else
               return;
            end if;

         --  Otherwise get the type's accessibility level normally

         else
            Type_Level :=
              Make_Integer_Literal (Loc, Deepest_Type_Access_Level (Typ));
         end if;

         --  Raise Program_Error if the accessibility level of the access
         --  parameter is deeper than the level of the target access type.

         Check_Cond :=
           Make_Op_Gt (Loc,
             Left_Opnd  => Param_Level,
             Right_Opnd => Type_Level);

         Insert_Action (Insert_Node,
           Make_Raise_Program_Error (Loc,
             Condition => Check_Cond,
             Reason    => PE_Accessibility_Check_Failed));

         Analyze_And_Resolve (N);

         --  If constant folding has happened on the condition for the
         --  generated error, then warn about it being unconditional.

         if Nkind (Check_Cond) = N_Identifier
           and then Entity (Check_Cond) = Standard_True
         then
            Error_Msg_Warn := SPARK_Mode /= On;
            Error_Msg_N ("accessibility check fails<<", N);
            Error_Msg_N ("\Program_Error [<<", N);
         end if;
      end if;
   end Apply_Accessibility_Check;

   --------------------------------
   -- Apply_Address_Clause_Check --
   --------------------------------

   procedure Apply_Address_Clause_Check (E : Entity_Id; N : Node_Id) is
      pragma Assert (Nkind (N) = N_Freeze_Entity);

      AC  : constant Node_Id    := Address_Clause (E);
      Loc : constant Source_Ptr := Sloc (AC);
      Typ : constant Entity_Id  := Etype (E);

      Expr : Node_Id;
      --  Address expression (not necessarily the same as Aexp, for example
      --  when Aexp is a reference to a constant, in which case Expr gets
      --  reset to reference the value expression of the constant).

   begin
      --  See if alignment check needed. Note that we never need a check if the
      --  maximum alignment is one, since the check will always succeed.

      --  Note: we do not check for checks suppressed here, since that check
      --  was done in Sem_Ch13 when the address clause was processed. We are
      --  only called if checks were not suppressed. The reason for this is
      --  that we have to delay the call to Apply_Alignment_Check till freeze
      --  time (so that all types etc are elaborated), but we have to check
      --  the status of check suppressing at the point of the address clause.

      if No (AC)
        or else not Check_Address_Alignment (AC)
        or else Maximum_Alignment = 1
      then
         return;
      end if;

      --  Obtain expression from address clause

      Expr := Address_Value (Expression (AC));

      --  See if we know that Expr has an acceptable value at compile time. If
      --  it hasn't or we don't know, we defer issuing the warning until the
      --  end of the compilation to take into account back end annotations.

      if Compile_Time_Known_Value (Expr)
        and then (Known_Alignment (E) or else Known_Alignment (Typ))
      then
         declare
            AL : Uint := Alignment (Typ);

         begin
            --  The object alignment might be more restrictive than the type
            --  alignment.

            if Known_Alignment (E) then
               AL := Alignment (E);
            end if;

            if Expr_Value (Expr) mod AL = 0 then
               return;
            end if;
         end;

      --  If the expression has the form X'Address, then we can find out if the
      --  object X has an alignment that is compatible with the object E. If it
      --  hasn't or we don't know, we defer issuing the warning until the end
      --  of the compilation to take into account back end annotations.

      elsif Nkind (Expr) = N_Attribute_Reference
        and then Attribute_Name (Expr) = Name_Address
        and then
          Has_Compatible_Alignment (E, Prefix (Expr), False) = Known_Compatible
      then
         return;
      end if;

      --  Here we do not know if the value is acceptable. Strictly we don't
      --  have to do anything, since if the alignment is bad, we have an
      --  erroneous program. However we are allowed to check for erroneous
      --  conditions and we decide to do this by default if the check is not
      --  suppressed.

      --  However, don't do the check if elaboration code is unwanted

      if Restriction_Active (No_Elaboration_Code) then
         return;

      --  Generate a check to raise PE if alignment may be inappropriate

      else
         --  If the original expression is a nonstatic constant, use the name
         --  of the constant itself rather than duplicating its initialization
         --  expression, which was extracted above.

         --  Note: Expr is empty if the address-clause is applied to in-mode
         --  actuals (allowed by 13.1(22)).

         if not Present (Expr)
           or else
             (Is_Entity_Name (Expression (AC))
               and then Ekind (Entity (Expression (AC))) = E_Constant
               and then Nkind (Parent (Entity (Expression (AC)))) =
                          N_Object_Declaration)
         then
            Expr := New_Copy_Tree (Expression (AC));
         else
            Remove_Side_Effects (Expr);
         end if;

         if No (Actions (N)) then
            Set_Actions (N, New_List);
         end if;

         Prepend_To (Actions (N),
           Make_Raise_Program_Error (Loc,
             Condition =>
               Make_Op_Ne (Loc,
                 Left_Opnd  =>
                   Make_Op_Mod (Loc,
                     Left_Opnd  =>
                       Unchecked_Convert_To
                         (RTE (RE_Integer_Address), Expr),
                     Right_Opnd =>
                       Make_Attribute_Reference (Loc,
                         Prefix         => New_Occurrence_Of (E, Loc),
                         Attribute_Name => Name_Alignment)),
                 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
             Reason    => PE_Misaligned_Address_Value));

         Warning_Msg := No_Error_Msg;
         Analyze (First (Actions (N)), Suppress => All_Checks);

         --  If the above raise action generated a warning message (for example
         --  from Warn_On_Non_Local_Exception mode with the active restriction
         --  No_Exception_Propagation).

         if Warning_Msg /= No_Error_Msg then

            --  If the expression has a known at compile time value, then
            --  once we know the alignment of the type, we can check if the
            --  exception will be raised or not, and if not, we don't need
            --  the warning so we will kill the warning later on.

            if Compile_Time_Known_Value (Expr) then
               Alignment_Warnings.Append
                 ((E => E,
                   A => Expr_Value (Expr),
                   P => Empty,
                   W => Warning_Msg));

            --  Likewise if the expression is of the form X'Address

            elsif Nkind (Expr) = N_Attribute_Reference
              and then Attribute_Name (Expr) = Name_Address
            then
               Alignment_Warnings.Append
                 ((E => E,
                   A => No_Uint,
                   P => Prefix (Expr),
                   W => Warning_Msg));

            --  Add explanation of the warning generated by the check

            else
               Error_Msg_N
                 ("\address value may be incompatible with alignment of "
                  & "object?X?", AC);
            end if;
         end if;

         return;
      end if;

   exception

      --  If we have some missing run time component in configurable run time
      --  mode then just skip the check (it is not required in any case).

      when RE_Not_Available =>
         return;
   end Apply_Address_Clause_Check;

   -------------------------------------
   -- Apply_Arithmetic_Overflow_Check --
   -------------------------------------

   procedure Apply_Arithmetic_Overflow_Check (N : Node_Id) is
   begin
      --  Use old routine in almost all cases (the only case we are treating
      --  specially is the case of a signed integer arithmetic op with the
      --  overflow checking mode set to MINIMIZED or ELIMINATED).

      if Overflow_Check_Mode = Strict
        or else not Is_Signed_Integer_Arithmetic_Op (N)
      then
         Apply_Arithmetic_Overflow_Strict (N);

      --  Otherwise use the new routine for the case of a signed integer
      --  arithmetic op, with Do_Overflow_Check set to True, and the checking
      --  mode is MINIMIZED or ELIMINATED.

      else
         Apply_Arithmetic_Overflow_Minimized_Eliminated (N);
      end if;
   end Apply_Arithmetic_Overflow_Check;

   --------------------------------------
   -- Apply_Arithmetic_Overflow_Strict --
   --------------------------------------

   --  This routine is called only if the type is an integer type and an
   --  arithmetic overflow check may be needed for op (add, subtract, or
   --  multiply). This check is performed if Backend_Overflow_Checks_On_Target
   --  is not enabled and Do_Overflow_Check is set. In this case we expand the
   --  operation into a more complex sequence of tests that ensures that
   --  overflow is properly caught.

   --  This is used in CHECKED modes. It is identical to the code for this
   --  cases before the big overflow earthquake, thus ensuring that in this
   --  modes we have compatible behavior (and reliability) to what was there
   --  before. It is also called for types other than signed integers, and if
   --  the Do_Overflow_Check flag is off.

   --  Note: we also call this routine if we decide in the MINIMIZED case
   --  to give up and just generate an overflow check without any fuss.

   procedure Apply_Arithmetic_Overflow_Strict (N : Node_Id) is
      Loc  : constant Source_Ptr := Sloc (N);
      Typ  : constant Entity_Id  := Etype (N);
      Rtyp : constant Entity_Id  := Root_Type (Typ);

   begin
      --  Nothing to do if Do_Overflow_Check not set or overflow checks
      --  suppressed.

      if not Do_Overflow_Check (N) then
         return;
      end if;

      --  An interesting special case. If the arithmetic operation appears as
      --  the operand of a type conversion:

      --    type1 (x op y)

      --  and all the following conditions apply:

      --    arithmetic operation is for a signed integer type
      --    target type type1 is a static integer subtype
      --    range of x and y are both included in the range of type1
      --    range of x op y is included in the range of type1
      --    size of type1 is at least twice the result size of op

      --  then we don't do an overflow check in any case. Instead, we transform
      --  the operation so that we end up with:

      --    type1 (type1 (x) op type1 (y))

      --  This avoids intermediate overflow before the conversion. It is
      --  explicitly permitted by RM 3.5.4(24):

      --    For the execution of a predefined operation of a signed integer
      --    type, the implementation need not raise Constraint_Error if the
      --    result is outside the base range of the type, so long as the
      --    correct result is produced.

      --  It's hard to imagine that any programmer counts on the exception
      --  being raised in this case, and in any case it's wrong coding to
      --  have this expectation, given the RM permission. Furthermore, other
      --  Ada compilers do allow such out of range results.

      --  Note that we do this transformation even if overflow checking is
      --  off, since this is precisely about giving the "right" result and
      --  avoiding the need for an overflow check.

      --  Note: this circuit is partially redundant with respect to the similar
      --  processing in Exp_Ch4.Expand_N_Type_Conversion, but the latter deals
      --  with cases that do not come through here. We still need the following
      --  processing even with the Exp_Ch4 code in place, since we want to be
      --  sure not to generate the arithmetic overflow check in these cases
      --  (Exp_Ch4 would have a hard time removing them once generated).

      if Is_Signed_Integer_Type (Typ)
        and then Nkind (Parent (N)) = N_Type_Conversion
      then
         Conversion_Optimization : declare
            Target_Type : constant Entity_Id :=
              Base_Type (Entity (Subtype_Mark (Parent (N))));

            Llo, Lhi : Uint;
            Rlo, Rhi : Uint;
            LOK, ROK : Boolean;

            Vlo : Uint;
            Vhi : Uint;
            VOK : Boolean;

            Tlo : Uint;
            Thi : Uint;

         begin
            if Is_Integer_Type (Target_Type)
              and then RM_Size (Root_Type (Target_Type)) >= 2 * RM_Size (Rtyp)
            then
               Tlo := Expr_Value (Type_Low_Bound  (Target_Type));
               Thi := Expr_Value (Type_High_Bound (Target_Type));

               Determine_Range
                 (Left_Opnd  (N), LOK, Llo, Lhi, Assume_Valid => True);
               Determine_Range
                 (Right_Opnd (N), ROK, Rlo, Rhi, Assume_Valid => True);

               if (LOK and ROK)
                 and then Tlo <= Llo and then Lhi <= Thi
                 and then Tlo <= Rlo and then Rhi <= Thi
               then
                  Determine_Range (N, VOK, Vlo, Vhi, Assume_Valid => True);

                  if VOK and then Tlo <= Vlo and then Vhi <= Thi then
                     Rewrite (Left_Opnd (N),
                       Make_Type_Conversion (Loc,
                         Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
                         Expression   => Relocate_Node (Left_Opnd (N))));

                     Rewrite (Right_Opnd (N),
                       Make_Type_Conversion (Loc,
                        Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
                        Expression   => Relocate_Node (Right_Opnd (N))));

                     --  Rewrite the conversion operand so that the original
                     --  node is retained, in order to avoid the warning for
                     --  redundant conversions in Resolve_Type_Conversion.

                     Rewrite (N, Relocate_Node (N));

                     Set_Etype (N, Target_Type);

                     Analyze_And_Resolve (Left_Opnd  (N), Target_Type);
                     Analyze_And_Resolve (Right_Opnd (N), Target_Type);

                     --  Given that the target type is twice the size of the
                     --  source type, overflow is now impossible, so we can
                     --  safely kill the overflow check and return.

                     Set_Do_Overflow_Check (N, False);
                     return;
                  end if;
               end if;
            end if;
         end Conversion_Optimization;
      end if;

      --  Now see if an overflow check is required

      declare
         Dsiz  : constant Uint := 2 * Esize (Rtyp);
         Opnod : Node_Id;
         Ctyp  : Entity_Id;
         Opnd  : Node_Id;
         Cent  : RE_Id;

      begin
         --  Skip check if back end does overflow checks, or the overflow flag
         --  is not set anyway, or we are not doing code expansion, or the
         --  parent node is a type conversion whose operand is an arithmetic
         --  operation on signed integers on which the expander can promote
         --  later the operands to type Integer (see Expand_N_Type_Conversion).

         if Backend_Overflow_Checks_On_Target
           or else not Do_Overflow_Check (N)
           or else not Expander_Active
           or else (Present (Parent (N))
                     and then Nkind (Parent (N)) = N_Type_Conversion
                     and then Integer_Promotion_Possible (Parent (N)))
         then
            return;
         end if;

         --  Otherwise, generate the full general code for front end overflow
         --  detection, which works by doing arithmetic in a larger type:

         --    x op y

         --  is expanded into

         --    Typ (Checktyp (x) op Checktyp (y));

         --  where Typ is the type of the original expression, and Checktyp is
         --  an integer type of sufficient length to hold the largest possible
         --  result.

         --  If the size of the check type exceeds the maximum integer size,
         --  we use a different approach, expanding to:

         --    typ (xxx_With_Ovflo_Check (Integer_NN (x), Integer_NN (y)))

         --  where xxx is Add, Multiply or Subtract as appropriate

         --  Find check type if one exists

         if Dsiz <= System_Max_Integer_Size then
            Ctyp := Integer_Type_For (Dsiz, Uns => False);

         --  No check type exists, use runtime call

         else
            if System_Max_Integer_Size = 64 then
               Ctyp := RTE (RE_Integer_64);
            else
               Ctyp := RTE (RE_Integer_128);
            end if;

            if Nkind (N) = N_Op_Add then
               if System_Max_Integer_Size = 64 then
                  Cent := RE_Add_With_Ovflo_Check64;
               else
                  Cent := RE_Add_With_Ovflo_Check128;
               end if;

            elsif Nkind (N) = N_Op_Subtract then
               if System_Max_Integer_Size = 64 then
                  Cent := RE_Subtract_With_Ovflo_Check64;
               else
                  Cent := RE_Subtract_With_Ovflo_Check128;
               end if;

            else pragma Assert (Nkind (N) = N_Op_Multiply);
               if System_Max_Integer_Size = 64 then
                  Cent := RE_Multiply_With_Ovflo_Check64;
               else
                  Cent := RE_Multiply_With_Ovflo_Check128;
               end if;
            end if;

            Rewrite (N,
              OK_Convert_To (Typ,
                Make_Function_Call (Loc,
                  Name => New_Occurrence_Of (RTE (Cent), Loc),
                  Parameter_Associations => New_List (
                    OK_Convert_To (Ctyp, Left_Opnd  (N)),
                    OK_Convert_To (Ctyp, Right_Opnd (N))))));

            Analyze_And_Resolve (N, Typ);
            return;
         end if;

         --  If we fall through, we have the case where we do the arithmetic
         --  in the next higher type and get the check by conversion. In these
         --  cases Ctyp is set to the type to be used as the check type.

         Opnod := Relocate_Node (N);

         Opnd := OK_Convert_To (Ctyp, Left_Opnd (Opnod));

         Analyze (Opnd);
         Set_Etype (Opnd, Ctyp);
         Set_Analyzed (Opnd, True);
         Set_Left_Opnd (Opnod, Opnd);

         Opnd := OK_Convert_To (Ctyp, Right_Opnd (Opnod));

         Analyze (Opnd);
         Set_Etype (Opnd, Ctyp);
         Set_Analyzed (Opnd, True);
         Set_Right_Opnd (Opnod, Opnd);

         --  The type of the operation changes to the base type of the check
         --  type, and we reset the overflow check indication, since clearly no
         --  overflow is possible now that we are using a double length type.
         --  We also set the Analyzed flag to avoid a recursive attempt to
         --  expand the node.

         Set_Etype             (Opnod, Base_Type (Ctyp));
         Set_Do_Overflow_Check (Opnod, False);
         Set_Analyzed          (Opnod, True);

         --  Now build the outer conversion

         Opnd := OK_Convert_To (Typ, Opnod);
         Analyze (Opnd);
         Set_Etype (Opnd, Typ);

         --  In the discrete type case, we directly generate the range check
         --  for the outer operand. This range check will implement the
         --  required overflow check.

         if Is_Discrete_Type (Typ) then
            Rewrite (N, Opnd);
            Generate_Range_Check
              (Expression (N), Typ, CE_Overflow_Check_Failed);

         --  For other types, we enable overflow checking on the conversion,
         --  after setting the node as analyzed to prevent recursive attempts
         --  to expand the conversion node.

         else
            Set_Analyzed (Opnd, True);
            Enable_Overflow_Check (Opnd);
            Rewrite (N, Opnd);
         end if;

      exception
         when RE_Not_Available =>
            return;
      end;
   end Apply_Arithmetic_Overflow_Strict;

   ----------------------------------------------------
   -- Apply_Arithmetic_Overflow_Minimized_Eliminated --
   ----------------------------------------------------

   procedure Apply_Arithmetic_Overflow_Minimized_Eliminated (Op : Node_Id) is
      pragma Assert (Is_Signed_Integer_Arithmetic_Op (Op));

      Loc : constant Source_Ptr := Sloc (Op);
      P   : constant Node_Id    := Parent (Op);

      LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
      --  Operands and results are of this type when we convert

      Result_Type : constant Entity_Id := Etype (Op);
      --  Original result type

      Check_Mode : constant Overflow_Mode_Type := Overflow_Check_Mode;
      pragma Assert (Check_Mode in Minimized_Or_Eliminated);

      Lo, Hi : Uint;
      --  Ranges of values for result

   begin
      --  Nothing to do if our parent is one of the following:

      --    Another signed integer arithmetic op
      --    A membership operation
      --    A comparison operation

      --  In all these cases, we will process at the higher level (and then
      --  this node will be processed during the downwards recursion that
      --  is part of the processing in Minimize_Eliminate_Overflows).

      if Is_Signed_Integer_Arithmetic_Op (P)
        or else Nkind (P) in N_Membership_Test
        or else Nkind (P) in N_Op_Compare

        --  This is also true for an alternative in a case expression

        or else Nkind (P) = N_Case_Expression_Alternative

        --  This is also true for a range operand in a membership test

        or else (Nkind (P) = N_Range
                  and then Nkind (Parent (P)) in N_Membership_Test)
      then
         --  If_Expressions and Case_Expressions are treated as arithmetic
         --  ops, but if they appear in an assignment or similar contexts
         --  there is no overflow check that starts from that parent node,
         --  so apply check now.

         if Nkind (P) in N_If_Expression | N_Case_Expression
           and then not Is_Signed_Integer_Arithmetic_Op (Parent (P))
         then
            null;
         else
            return;
         end if;
      end if;

      --  Otherwise, we have a top level arithmetic operation node, and this
      --  is where we commence the special processing for MINIMIZED/ELIMINATED
      --  modes. This is the case where we tell the machinery not to move into
      --  Bignum mode at this top level (of course the top level operation
      --  will still be in Bignum mode if either of its operands are of type
      --  Bignum).

      Minimize_Eliminate_Overflows (Op, Lo, Hi, Top_Level => True);

      --  That call may but does not necessarily change the result type of Op.
      --  It is the job of this routine to undo such changes, so that at the
      --  top level, we have the proper type. This "undoing" is a point at
      --  which a final overflow check may be applied.

      --  If the result type was not fiddled we are all set. We go to base
      --  types here because things may have been rewritten to generate the
      --  base type of the operand types.

      if Base_Type (Etype (Op)) = Base_Type (Result_Type) then
         return;

      --  Bignum case

      elsif Is_RTE (Etype (Op), RE_Bignum) then

         --  We need a sequence that looks like:

         --    Rnn : Result_Type;

         --    declare
         --       M : Mark_Id := SS_Mark;
         --    begin
         --       Rnn := Long_Long_Integer'Base (From_Bignum (Op));
         --       SS_Release (M);
         --    end;

         --  This block is inserted (using Insert_Actions), and then the node
         --  is replaced with a reference to Rnn.

         --  If our parent is a conversion node then there is no point in
         --  generating a conversion to Result_Type. Instead, we let the parent
         --  handle this. Note that this special case is not just about
         --  optimization. Consider

         --      A,B,C : Integer;
         --      ...
         --      X := Long_Long_Integer'Base (A * (B ** C));

         --  Now the product may fit in Long_Long_Integer but not in Integer.
         --  In MINIMIZED/ELIMINATED mode, we don't want to introduce an
         --  overflow exception for this intermediate value.

         declare
            Blk : constant Node_Id  := Make_Bignum_Block (Loc);
            Rnn : constant Entity_Id := Make_Temporary (Loc, 'R', Op);
            RHS : Node_Id;

            Rtype : Entity_Id;

         begin
            RHS := Convert_From_Bignum (Op);

            if Nkind (P) /= N_Type_Conversion then
               Convert_To_And_Rewrite (Result_Type, RHS);
               Rtype := Result_Type;

               --  Interesting question, do we need a check on that conversion
               --  operation. Answer, not if we know the result is in range.
               --  At the moment we are not taking advantage of this. To be
               --  looked at later ???

            else
               Rtype := LLIB;
            end if;

            Insert_Before
              (First (Statements (Handled_Statement_Sequence (Blk))),
               Make_Assignment_Statement (Loc,
                 Name       => New_Occurrence_Of (Rnn, Loc),
                 Expression => RHS));

            Insert_Actions (Op, New_List (
              Make_Object_Declaration (Loc,
                Defining_Identifier => Rnn,
                Object_Definition   => New_Occurrence_Of (Rtype, Loc)),
              Blk));

            Rewrite (Op, New_Occurrence_Of (Rnn, Loc));
            Analyze_And_Resolve (Op);
         end;

      --  Here we know the result is Long_Long_Integer'Base, or that it has
      --  been rewritten because the parent operation is a conversion. See
      --  Apply_Arithmetic_Overflow_Strict.Conversion_Optimization.

      else
         pragma Assert
           (Etype (Op) = LLIB or else Nkind (Parent (Op)) = N_Type_Conversion);

         --  All we need to do here is to convert the result to the proper
         --  result type. As explained above for the Bignum case, we can
         --  omit this if our parent is a type conversion.

         if Nkind (P) /= N_Type_Conversion then
            Convert_To_And_Rewrite (Result_Type, Op);
         end if;

         Analyze_And_Resolve (Op);
      end if;
   end Apply_Arithmetic_Overflow_Minimized_Eliminated;

   ----------------------------
   -- Apply_Constraint_Check --
   ----------------------------

   procedure Apply_Constraint_Check
     (N          : Node_Id;
      Typ        : Entity_Id;
      No_Sliding : Boolean := False)
   is
      Desig_Typ : Entity_Id;

   begin
      --  No checks inside a generic (check the instantiations)

      if Inside_A_Generic then
         return;
      end if;

      --  Apply required constraint checks

      if Is_Scalar_Type (Typ) then
         Apply_Scalar_Range_Check (N, Typ);

      elsif Is_Array_Type (Typ) then

         --  A useful optimization: an aggregate with only an others clause
         --  always has the right bounds.

         if Nkind (N) = N_Aggregate
           and then No (Expressions (N))
           and then Nkind
            (First (Choices (First (Component_Associations (N)))))
              = N_Others_Choice
         then
            return;
         end if;

         if Is_Constrained (Typ) then
            Apply_Length_Check (N, Typ);

            if No_Sliding then
               Apply_Range_Check (N, Typ);
            end if;
         else
            Apply_Range_Check (N, Typ);
         end if;

      elsif (Is_Record_Type (Typ) or else Is_Private_Type (Typ))
        and then Has_Discriminants (Base_Type (Typ))
        and then Is_Constrained (Typ)
      then
         Apply_Discriminant_Check (N, Typ);

      elsif Is_Access_Type (Typ) then

         Desig_Typ := Designated_Type (Typ);

         --  No checks necessary if expression statically null

         if Known_Null (N) then
            if Can_Never_Be_Null (Typ) then
               Install_Null_Excluding_Check (N);
            end if;

         --  No sliding possible on access to arrays

         elsif Is_Array_Type (Desig_Typ) then
            if Is_Constrained (Desig_Typ) then
               Apply_Length_Check (N, Typ);
            end if;

            Apply_Range_Check (N, Typ);

         --  Do not install a discriminant check for a constrained subtype
         --  created for an unconstrained nominal type because the subtype
         --  has the correct constraints by construction.

         elsif Has_Discriminants (Base_Type (Desig_Typ))
           and then Is_Constrained (Desig_Typ)
           and then not Is_Constr_Subt_For_U_Nominal (Desig_Typ)
         then
            Apply_Discriminant_Check (N, Typ);
         end if;

         --  Apply the 2005 Null_Excluding check. Note that we do not apply
         --  this check if the constraint node is illegal, as shown by having
         --  an error posted. This additional guard prevents cascaded errors
         --  and compiler aborts on illegal programs involving Ada 2005 checks.

         if Can_Never_Be_Null (Typ)
           and then not Can_Never_Be_Null (Etype (N))
           and then not Error_Posted (N)
         then
            Install_Null_Excluding_Check (N);
         end if;
      end if;
   end Apply_Constraint_Check;

   ------------------------------
   -- Apply_Discriminant_Check --
   ------------------------------

   procedure Apply_Discriminant_Check
     (N   : Node_Id;
      Typ : Entity_Id;
      Lhs : Node_Id := Empty)
   is
      Loc       : constant Source_Ptr := Sloc (N);
      Do_Access : constant Boolean    := Is_Access_Type (Typ);
      S_Typ     : Entity_Id  := Etype (N);
      Cond      : Node_Id;
      T_Typ     : Entity_Id;

      function Denotes_Explicit_Dereference (Obj : Node_Id) return Boolean;
      --  A heap object with an indefinite subtype is constrained by its
      --  initial value, and assigning to it requires a constraint_check.
      --  The target may be an explicit dereference, or a renaming of one.

      function Is_Aliased_Unconstrained_Component return Boolean;
      --  It is possible for an aliased component to have a nominal
      --  unconstrained subtype (through instantiation). If this is a
      --  discriminated component assigned in the expansion of an aggregate
      --  in an initialization, the check must be suppressed. This unusual
      --  situation requires a predicate of its own.

      ----------------------------------
      -- Denotes_Explicit_Dereference --
      ----------------------------------

      function Denotes_Explicit_Dereference (Obj : Node_Id) return Boolean is
      begin
         return
           Nkind (Obj) = N_Explicit_Dereference
             or else
               (Is_Entity_Name (Obj)
                 and then Present (Renamed_Object (Entity (Obj)))
                 and then Nkind (Renamed_Object (Entity (Obj))) =
                                              N_Explicit_Dereference);
      end Denotes_Explicit_Dereference;

      ----------------------------------------
      -- Is_Aliased_Unconstrained_Component --
      ----------------------------------------

      function Is_Aliased_Unconstrained_Component return Boolean is
         Comp : Entity_Id;
         Pref : Node_Id;

      begin
         if Nkind (Lhs) /= N_Selected_Component then
            return False;
         else
            Comp := Entity (Selector_Name (Lhs));
            Pref := Prefix (Lhs);
         end if;

         if Ekind (Comp) /= E_Component
           or else not Is_Aliased (Comp)
         then
            return False;
         end if;

         return not Comes_From_Source (Pref)
           and then In_Instance
           and then not Is_Constrained (Etype (Comp));
      end Is_Aliased_Unconstrained_Component;

   --  Start of processing for Apply_Discriminant_Check

   begin
      if Do_Access then
         T_Typ := Designated_Type (Typ);
      else
         T_Typ := Typ;
      end if;

      --  If the expression is a function call that returns a limited object
      --  it cannot be copied. It is not clear how to perform the proper
      --  discriminant check in this case because the discriminant value must
      --  be retrieved from the constructed object itself.

      if Nkind (N) = N_Function_Call
        and then Is_Limited_Type (Typ)
        and then Is_Entity_Name (Name (N))
        and then Returns_By_Ref (Entity (Name (N)))
      then
         return;
      end if;

      --  Only apply checks when generating code and discriminant checks are
      --  not suppressed. In GNATprove mode, we do not apply the checks, but we
      --  still analyze the expression to possibly issue errors on SPARK code
      --  when a run-time error can be detected at compile time.

      if not GNATprove_Mode then
         if not Expander_Active
           or else Discriminant_Checks_Suppressed (T_Typ)
         then
            return;
         end if;
      end if;

      --  No discriminant checks necessary for an access when expression is
      --  statically Null. This is not only an optimization, it is fundamental
      --  because otherwise discriminant checks may be generated in init procs
      --  for types containing an access to a not-yet-frozen record, causing a
      --  deadly forward reference.

      --  Also, if the expression is of an access type whose designated type is
      --  incomplete, then the access value must be null and we suppress the
      --  check.

      if Known_Null (N) then
         return;

      elsif Is_Access_Type (S_Typ) then
         S_Typ := Designated_Type (S_Typ);

         if Ekind (S_Typ) = E_Incomplete_Type then
            return;
         end if;
      end if;

      --  If an assignment target is present, then we need to generate the
      --  actual subtype if the target is a parameter or aliased object with
      --  an unconstrained nominal subtype.

      --  Ada 2005 (AI-363): For Ada 2005, we limit the building of the actual
      --  subtype to the parameter and dereference cases, since other aliased
      --  objects are unconstrained (unless the nominal subtype is explicitly
      --  constrained).

      if Present (Lhs)
        and then (Present (Param_Entity (Lhs))
                   or else (Ada_Version < Ada_2005
                             and then not Is_Constrained (T_Typ)
                             and then Is_Aliased_View (Lhs)
                             and then not Is_Aliased_Unconstrained_Component)
                   or else (Ada_Version >= Ada_2005
                             and then not Is_Constrained (T_Typ)
                             and then Denotes_Explicit_Dereference (Lhs)
                             and then Nkind (Original_Node (Lhs)) /=
                                        N_Function_Call))
      then
         T_Typ := Get_Actual_Subtype (Lhs);
      end if;

      --  Nothing to do if the type is unconstrained (this is the case where
      --  the actual subtype in the RM sense of N is unconstrained and no check
      --  is required).

      if not Is_Constrained (T_Typ) then
         return;

      --  Ada 2005: nothing to do if the type is one for which there is a
      --  partial view that is constrained.

      elsif Ada_Version >= Ada_2005
        and then Object_Type_Has_Constrained_Partial_View
                   (Typ  => Base_Type (T_Typ),
                    Scop => Current_Scope)
      then
         return;
      end if;

      --  Nothing to do if the type is an Unchecked_Union

      if Is_Unchecked_Union (Base_Type (T_Typ)) then
         return;
      end if;

      --  Suppress checks if the subtypes are the same. The check must be
      --  preserved in an assignment to a formal, because the constraint is
      --  given by the actual.

      if Nkind (Original_Node (N)) /= N_Allocator
        and then (No (Lhs)
                   or else not Is_Entity_Name (Lhs)
                   or else No (Param_Entity (Lhs)))
      then
         if (Etype (N) = Typ
              or else (Do_Access and then Designated_Type (Typ) = S_Typ))
           and then not Is_Aliased_View (Lhs)
         then
            return;
         end if;

      --  We can also eliminate checks on allocators with a subtype mark that
      --  coincides with the context type. The context type may be a subtype
      --  without a constraint (common case, a generic actual).

      elsif Nkind (Original_Node (N)) = N_Allocator
        and then Is_Entity_Name (Expression (Original_Node (N)))
      then
         declare
            Alloc_Typ : constant Entity_Id :=
              Entity (Expression (Original_Node (N)));

         begin
            if Alloc_Typ = T_Typ
              or else (Nkind (Parent (T_Typ)) = N_Subtype_Declaration
                        and then Is_Entity_Name (
                          Subtype_Indication (Parent (T_Typ)))
                        and then Alloc_Typ = Base_Type (T_Typ))

            then
               return;
            end if;
         end;
      end if;

      --  See if we have a case where the types are both constrained, and all
      --  the constraints are constants. In this case, we can do the check
      --  successfully at compile time.

      --  We skip this check for the case where the node is rewritten as
      --  an allocator, because it already carries the context subtype,
      --  and extracting the discriminants from the aggregate is messy.

      if Is_Constrained (S_Typ)
        and then Nkind (Original_Node (N)) /= N_Allocator
      then
         declare
            DconT : Elmt_Id;
            Discr : Entity_Id;
            DconS : Elmt_Id;
            ItemS : Node_Id;
            ItemT : Node_Id;

         begin
            --  S_Typ may not have discriminants in the case where it is a
            --  private type completed by a default discriminated type. In that
            --  case, we need to get the constraints from the underlying type.
            --  If the underlying type is unconstrained (i.e. has no default
            --  discriminants) no check is needed.

            if Has_Discriminants (S_Typ) then
               Discr := First_Discriminant (S_Typ);
               DconS := First_Elmt (Discriminant_Constraint (S_Typ));

            else
               Discr := First_Discriminant (Underlying_Type (S_Typ));
               DconS :=
                 First_Elmt
                   (Discriminant_Constraint (Underlying_Type (S_Typ)));

               if No (DconS) then
                  return;
               end if;

               --  A further optimization: if T_Typ is derived from S_Typ
               --  without imposing a constraint, no check is needed.

               if Nkind (Original_Node (Parent (T_Typ))) =
                 N_Full_Type_Declaration
               then
                  declare
                     Type_Def : constant Node_Id :=
                       Type_Definition (Original_Node (Parent (T_Typ)));
                  begin
                     if Nkind (Type_Def) = N_Derived_Type_Definition
                       and then Is_Entity_Name (Subtype_Indication (Type_Def))
                       and then Entity (Subtype_Indication (Type_Def)) = S_Typ
                     then
                        return;
                     end if;
                  end;
               end if;
            end if;

            --  Constraint may appear in full view of type

            if Ekind (T_Typ) = E_Private_Subtype
              and then Present (Full_View (T_Typ))
            then
               DconT :=
                 First_Elmt (Discriminant_Constraint (Full_View (T_Typ)));
            else
               DconT :=
                 First_Elmt (Discriminant_Constraint (T_Typ));
            end if;

            while Present (Discr) loop
               ItemS := Node (DconS);
               ItemT := Node (DconT);

               --  For a discriminated component type constrained by the
               --  current instance of an enclosing type, there is no
               --  applicable discriminant check.

               if Nkind (ItemT) = N_Attribute_Reference
                 and then Is_Access_Type (Etype (ItemT))
                 and then Is_Entity_Name (Prefix (ItemT))
                 and then Is_Type (Entity (Prefix (ItemT)))
               then
                  return;
               end if;

               --  If the expressions for the discriminants are identical
               --  and it is side-effect free (for now just an entity),
               --  this may be a shared constraint, e.g. from a subtype
               --  without a constraint introduced as a generic actual.
               --  Examine other discriminants if any.

               if ItemS = ItemT
                 and then Is_Entity_Name (ItemS)
               then
                  null;

               elsif not Is_OK_Static_Expression (ItemS)
                 or else not Is_OK_Static_Expression (ItemT)
               then
                  exit;

               elsif Expr_Value (ItemS) /= Expr_Value (ItemT) then
                  if Do_Access then   --  needs run-time check.
                     exit;
                  else
                     Apply_Compile_Time_Constraint_Error
                       (N, "incorrect value for discriminant&??",
                        CE_Discriminant_Check_Failed, Ent => Discr);
                     return;
                  end if;
               end if;

               Next_Elmt (DconS);
               Next_Elmt (DconT);
               Next_Discriminant (Discr);
            end loop;

            if No (Discr) then
               return;
            end if;
         end;
      end if;

      --  In GNATprove mode, we do not apply the checks

      if GNATprove_Mode then
         return;
      end if;

      --  Here we need a discriminant check. First build the expression
      --  for the comparisons of the discriminants:

      --    (n.disc1 /= typ.disc1) or else
      --    (n.disc2 /= typ.disc2) or else
      --     ...
      --    (n.discn /= typ.discn)

      Cond := Build_Discriminant_Checks (N, T_Typ);

      --  If Lhs is set and is a parameter, then the condition is guarded by:
      --  lhs'constrained and then (condition built above)

      if Present (Param_Entity (Lhs)) then
         Cond :=
           Make_And_Then (Loc,
             Left_Opnd =>
               Make_Attribute_Reference (Loc,
                 Prefix => New_Occurrence_Of (Param_Entity (Lhs), Loc),
                 Attribute_Name => Name_Constrained),
             Right_Opnd => Cond);
      end if;

      if Do_Access then
         Cond := Guard_Access (Cond, Loc, N);
      end if;

      Insert_Action (N,
        Make_Raise_Constraint_Error (Loc,
          Condition => Cond,
          Reason    => CE_Discriminant_Check_Failed));
   end Apply_Discriminant_Check;

   -------------------------
   -- Apply_Divide_Checks --
   -------------------------

   procedure Apply_Divide_Checks (N : Node_Id) is
      Loc   : constant Source_Ptr := Sloc (N);
      Typ   : constant Entity_Id  := Etype (N);
      Left  : constant Node_Id    := Left_Opnd (N);
      Right : constant Node_Id    := Right_Opnd (N);

      Mode : constant Overflow_Mode_Type := Overflow_Check_Mode;
      --  Current overflow checking mode

      LLB : Uint;
      Llo : Uint;
      Lhi : Uint;
      LOK : Boolean;
      Rlo : Uint;
      Rhi : Uint;
      ROK : Boolean;

      pragma Warnings (Off, Lhi);
      --  Don't actually use this value

   begin
      --  If we are operating in MINIMIZED or ELIMINATED mode, and we are
      --  operating on signed integer types, then the only thing this routine
      --  does is to call Apply_Arithmetic_Overflow_Minimized_Eliminated. That
      --  procedure will (possibly later on during recursive downward calls),
      --  ensure that any needed overflow/division checks are properly applied.

      if Mode in Minimized_Or_Eliminated
        and then Is_Signed_Integer_Type (Typ)
      then
         Apply_Arithmetic_Overflow_Minimized_Eliminated (N);
         return;
      end if;

      --  Proceed here in SUPPRESSED or CHECKED modes

      if Expander_Active
        and then not Backend_Divide_Checks_On_Target
        and then Check_Needed (Right, Division_Check)
      then
         Determine_Range (Right, ROK, Rlo, Rhi, Assume_Valid => True);

         --  Deal with division check

         if Do_Division_Check (N)
           and then not Division_Checks_Suppressed (Typ)
         then
            Apply_Division_Check (N, Rlo, Rhi, ROK);
         end if;

         --  Deal with overflow check

         if Do_Overflow_Check (N)
           and then not Overflow_Checks_Suppressed (Etype (N))
         then
            Set_Do_Overflow_Check (N, False);

            --  Test for extremely annoying case of xxx'First divided by -1
            --  for division of signed integer types (only overflow case).

            if Nkind (N) = N_Op_Divide
              and then Is_Signed_Integer_Type (Typ)
            then
               Determine_Range (Left, LOK, Llo, Lhi, Assume_Valid => True);
               LLB := Expr_Value (Type_Low_Bound (Base_Type (Typ)));

               if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
                     and then
                  ((not LOK) or else (Llo = LLB))
               then
                  --  Ensure that expressions are not evaluated twice (once
                  --  for their runtime checks and once for their regular
                  --  computation).

                  Force_Evaluation (Left, Mode => Strict);
                  Force_Evaluation (Right, Mode => Strict);

                  Insert_Action (N,
                    Make_Raise_Constraint_Error (Loc,
                      Condition =>
                        Make_And_Then (Loc,
                          Left_Opnd  =>
                            Make_Op_Eq (Loc,
                              Left_Opnd  =>
                                Duplicate_Subexpr_Move_Checks (Left),
                              Right_Opnd => Make_Integer_Literal (Loc, LLB)),

                          Right_Opnd =>
                            Make_Op_Eq (Loc,
                              Left_Opnd  => Duplicate_Subexpr (Right),
                              Right_Opnd => Make_Integer_Literal (Loc, -1))),

                      Reason => CE_Overflow_Check_Failed));
               end if;
            end if;
         end if;
      end if;
   end Apply_Divide_Checks;

   --------------------------
   -- Apply_Division_Check --
   --------------------------

   procedure Apply_Division_Check
     (N   : Node_Id;
      Rlo : Uint;
      Rhi : Uint;
      ROK : Boolean)
   is
      pragma Assert (Do_Division_Check (N));

      Loc   : constant Source_Ptr := Sloc (N);
      Right : constant Node_Id := Right_Opnd (N);
      Opnd  : Node_Id;

   begin
      if Expander_Active
        and then not Backend_Divide_Checks_On_Target
        and then Check_Needed (Right, Division_Check)

        --  See if division by zero possible, and if so generate test. This
        --  part of the test is not controlled by the -gnato switch, since it
        --  is a Division_Check and not an Overflow_Check.

        and then Do_Division_Check (N)
      then
         Set_Do_Division_Check (N, False);

         if (not ROK) or else (Rlo <= 0 and then 0 <= Rhi) then
            if Is_Floating_Point_Type (Etype (N)) then
               Opnd := Make_Real_Literal (Loc, Ureal_0);
            else
               Opnd := Make_Integer_Literal (Loc, 0);
            end if;

            Insert_Action (N,
              Make_Raise_Constraint_Error (Loc,
                Condition =>
                  Make_Op_Eq (Loc,
                    Left_Opnd  => Duplicate_Subexpr_Move_Checks (Right),
                    Right_Opnd => Opnd),
                Reason    => CE_Divide_By_Zero));
         end if;
      end if;
   end Apply_Division_Check;

   ----------------------------------
   -- Apply_Float_Conversion_Check --
   ----------------------------------

   --  Let F and I be the source and target types of the conversion. The RM
   --  specifies that a floating-point value X is rounded to the nearest
   --  integer, with halfway cases being rounded away from zero. The rounded
   --  value of X is checked against I'Range.

   --  The catch in the above paragraph is that there is no good way to know
   --  whether the round-to-integer operation resulted in overflow. A remedy is
   --  to perform a range check in the floating-point domain instead, however:

   --      (1)  The bounds may not be known at compile time
   --      (2)  The check must take into account rounding or truncation.
   --      (3)  The range of type I may not be exactly representable in F.
   --      (4)  For the rounding case, the end-points I'First - 0.5 and
   --           I'Last + 0.5 may or may not be in range, depending on the
   --           sign of  I'First and I'Last.
   --      (5)  X may be a NaN, which will fail any comparison

   --  The following steps correctly convert X with rounding:

   --      (1) If either I'First or I'Last is not known at compile time, use
   --          I'Base instead of I in the next three steps and perform a
   --          regular range check against I'Range after conversion.
   --      (2) If I'First - 0.5 is representable in F then let Lo be that
   --          value and define Lo_OK as (I'First > 0). Otherwise, let Lo be
   --          F'Machine (I'First) and let Lo_OK be (Lo >= I'First).
   --          In other words, take one of the closest floating-point numbers
   --          (which is an integer value) to I'First, and see if it is in
   --          range or not.
   --      (3) If I'Last + 0.5 is representable in F then let Hi be that value
   --          and define Hi_OK as (I'Last < 0). Otherwise, let Hi be
   --          F'Machine (I'Last) and let Hi_OK be (Hi <= I'Last).
   --      (4) Raise CE when (Lo_OK and X < Lo) or (not Lo_OK and X <= Lo)
   --                     or (Hi_OK and X > Hi) or (not Hi_OK and X >= Hi)

   --  For the truncating case, replace steps (2) and (3) as follows:
   --      (2) If I'First > 0, then let Lo be F'Pred (I'First) and let Lo_OK
   --          be False. Otherwise, let Lo be F'Succ (I'First - 1) and let
   --          Lo_OK be True.
   --      (3) If I'Last < 0, then let Hi be F'Succ (I'Last) and let Hi_OK
   --          be False. Otherwise let Hi be F'Pred (I'Last + 1) and let
   --          Hi_OK be True.

   procedure Apply_Float_Conversion_Check
     (Expr       : Node_Id;
      Target_Typ : Entity_Id)
   is
      LB          : constant Node_Id    := Type_Low_Bound (Target_Typ);
      HB          : constant Node_Id    := Type_High_Bound (Target_Typ);
      Loc         : constant Source_Ptr := Sloc (Expr);
      Expr_Type   : constant Entity_Id  := Base_Type (Etype (Expr));
      Target_Base : constant Entity_Id  :=
        Implementation_Base_Type (Target_Typ);

      Par : constant Node_Id := Parent (Expr);
      pragma Assert (Nkind (Par) = N_Type_Conversion);
      --  Parent of check node, must be a type conversion

      Truncate  : constant Boolean := Float_Truncate (Par);
      Max_Bound : constant Uint :=
        UI_Expon
          (Machine_Radix_Value (Expr_Type),
           Machine_Mantissa_Value (Expr_Type) - 1) - 1;

      --  Largest bound, so bound plus or minus half is a machine number of F

      Ifirst, Ilast : Uint;
      --  Bounds of integer type

      Lo, Hi : Ureal;
      --  Bounds to check in floating-point domain

      Lo_OK, Hi_OK : Boolean;
      --  True iff Lo resp. Hi belongs to I'Range

      Lo_Chk, Hi_Chk : Node_Id;
      --  Expressions that are False iff check fails

      Reason : RT_Exception_Code;

   begin
      --  We do not need checks if we are not generating code (i.e. the full
      --  expander is not active). In SPARK mode, we specifically don't want
      --  the frontend to expand these checks, which are dealt with directly
      --  in the formal verification backend.

      if not Expander_Active then
         return;
      end if;

      --  Here we will generate an explicit range check, so we don't want to
      --  set the Do_Range check flag, since the range check is taken care of
      --  by the code we will generate.

      Set_Do_Range_Check (Expr, False);

      if not Compile_Time_Known_Value (LB)
          or not Compile_Time_Known_Value (HB)
      then
         declare
            --  First check that the value falls in the range of the base type,
            --  to prevent overflow during conversion and then perform a
            --  regular range check against the (dynamic) bounds.

            pragma Assert (Target_Base /= Target_Typ);

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

         begin
            Apply_Float_Conversion_Check (Expr, Target_Base);
            Set_Etype (Temp, Target_Base);

            --  Note: Previously the declaration was inserted above the parent
            --  of the conversion, apparently as a small optimization for the
            --  subequent traversal in Insert_Actions. Unfortunately a similar
            --  optimization takes place in Insert_Actions, assuming that the
            --  insertion point must be above the expression that creates
            --  actions. This is not correct in the presence of conditional
            --  expressions, where the insertion must be in the list of actions
            --  attached to the current alternative.

            Insert_Action (Par,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Temp,
                Object_Definition => New_Occurrence_Of (Target_Typ, Loc),
                Expression => New_Copy_Tree (Par)),
                Suppress => All_Checks);

            Insert_Action (Par,
              Make_Raise_Constraint_Error (Loc,
                Condition =>
                  Make_Not_In (Loc,
                    Left_Opnd  => New_Occurrence_Of (Temp, Loc),
                    Right_Opnd => New_Occurrence_Of (Target_Typ, Loc)),
                Reason => CE_Range_Check_Failed));
            Rewrite (Par, New_Occurrence_Of (Temp, Loc));

            return;
         end;
      end if;

      --  Get the (static) bounds of the target type

      Ifirst := Expr_Value (LB);
      Ilast  := Expr_Value (HB);

      --  A simple optimization: if the expression is a universal literal,
      --  we can do the comparison with the bounds and the conversion to
      --  an integer type statically. The range checks are unchanged.

      if Nkind (Expr) = N_Real_Literal
        and then Etype (Expr) = Universal_Real
        and then Is_Integer_Type (Target_Typ)
      then
         declare
            Int_Val : constant Uint := UR_To_Uint (Realval (Expr));

         begin
            if Int_Val <= Ilast and then Int_Val >= Ifirst then

               --  Conversion is safe

               Rewrite (Parent (Expr),
                 Make_Integer_Literal (Loc, UI_To_Int (Int_Val)));
               Analyze_And_Resolve (Parent (Expr), Target_Typ);
               return;
            end if;
         end;
      end if;

      --  Check against lower bound

      if Truncate and then Ifirst > 0 then
         Lo := Pred (Expr_Type, UR_From_Uint (Ifirst));
         Lo_OK := False;

      elsif Truncate then
         Lo := Succ (Expr_Type, UR_From_Uint (Ifirst - 1));
         Lo_OK := True;

      elsif abs (Ifirst) < Max_Bound then
         Lo := UR_From_Uint (Ifirst) - Ureal_Half;
         Lo_OK := (Ifirst > 0);

      else
         Lo := Machine (Expr_Type, UR_From_Uint (Ifirst), Round_Even, Expr);
         Lo_OK := (Lo >= UR_From_Uint (Ifirst));
      end if;

      --  Saturate the lower bound to that of the expression's type, because
      --  we do not want to create an out-of-range value but we still need to
      --  do a comparison to catch NaNs.

      if Lo < Expr_Value_R (Type_Low_Bound (Expr_Type)) then
         Lo := Expr_Value_R (Type_Low_Bound (Expr_Type));
         Lo_OK := True;
      end if;

      if Lo_OK then

         --  Lo_Chk := (X >= Lo)

         Lo_Chk := Make_Op_Ge (Loc,
                     Left_Opnd => Duplicate_Subexpr_No_Checks (Expr),
                     Right_Opnd => Make_Real_Literal (Loc, Lo));

      else
         --  Lo_Chk := (X > Lo)

         Lo_Chk := Make_Op_Gt (Loc,
                     Left_Opnd => Duplicate_Subexpr_No_Checks (Expr),
                     Right_Opnd => Make_Real_Literal (Loc, Lo));
      end if;

      --  Check against higher bound

      if Truncate and then Ilast < 0 then
         Hi := Succ (Expr_Type, UR_From_Uint (Ilast));
         Hi_OK := False;

      elsif Truncate then
         Hi := Pred (Expr_Type, UR_From_Uint (Ilast + 1));
         Hi_OK := True;

      elsif abs (Ilast) < Max_Bound then
         Hi := UR_From_Uint (Ilast) + Ureal_Half;
         Hi_OK := (Ilast < 0);
      else
         Hi := Machine (Expr_Type, UR_From_Uint (Ilast), Round_Even, Expr);
         Hi_OK := (Hi <= UR_From_Uint (Ilast));
      end if;

      --  Saturate the higher bound to that of the expression's type, because
      --  we do not want to create an out-of-range value but we still need to
      --  do a comparison to catch NaNs.

      if Hi > Expr_Value_R (Type_High_Bound (Expr_Type)) then
         Hi := Expr_Value_R (Type_High_Bound (Expr_Type));
         Hi_OK := True;
      end if;

      if Hi_OK then

         --  Hi_Chk := (X <= Hi)

         Hi_Chk := Make_Op_Le (Loc,
                     Left_Opnd => Duplicate_Subexpr_No_Checks (Expr),
                     Right_Opnd => Make_Real_Literal (Loc, Hi));

      else
         --  Hi_Chk := (X < Hi)

         Hi_Chk := Make_Op_Lt (Loc,
                     Left_Opnd => Duplicate_Subexpr_No_Checks (Expr),
                     Right_Opnd => Make_Real_Literal (Loc, Hi));
      end if;

      --  If the bounds of the target type are the same as those of the base
      --  type, the check is an overflow check as a range check is not
      --  performed in these cases.

      if Expr_Value (Type_Low_Bound (Target_Base)) = Ifirst
        and then Expr_Value (Type_High_Bound (Target_Base)) = Ilast
      then
         Reason := CE_Overflow_Check_Failed;
      else
         Reason := CE_Range_Check_Failed;
      end if;

      --  Raise CE if either conditions does not hold

      Insert_Action (Expr,
        Make_Raise_Constraint_Error (Loc,
          Condition => Make_Op_Not (Loc, Make_And_Then (Loc, Lo_Chk, Hi_Chk)),
          Reason    => Reason));
   end Apply_Float_Conversion_Check;

   ------------------------
   -- Apply_Length_Check --
   ------------------------

   procedure Apply_Length_Check
     (Expr       : Node_Id;
      Target_Typ : Entity_Id;
      Source_Typ : Entity_Id := Empty)
   is
   begin
      Apply_Selected_Length_Checks
        (Expr, Target_Typ, Source_Typ, Do_Static => False);
   end Apply_Length_Check;

   --------------------------------------
   -- Apply_Length_Check_On_Assignment --
   --------------------------------------

   procedure Apply_Length_Check_On_Assignment
     (Expr       : Node_Id;
      Target_Typ : Entity_Id;
      Target     : Node_Id;
      Source_Typ : Entity_Id := Empty)
   is
      Assign : constant Node_Id := Parent (Target);

   begin
      --  No check is needed for the initialization of an object whose
      --  nominal subtype is unconstrained.

      if Is_Constr_Subt_For_U_Nominal (Target_Typ)
        and then Nkind (Parent (Assign)) = N_Freeze_Entity
        and then Is_Entity_Name (Target)
        and then Entity (Target) = Entity (Parent (Assign))
      then
         return;
      end if;

      Apply_Selected_Length_Checks
        (Expr, Target_Typ, Source_Typ, Do_Static => False);
   end Apply_Length_Check_On_Assignment;

   -------------------------------------
   -- Apply_Parameter_Aliasing_Checks --
   -------------------------------------

   procedure Apply_Parameter_Aliasing_Checks
     (Call : Node_Id;
      Subp : Entity_Id)
   is
      Loc : constant Source_Ptr := Sloc (Call);

      function Parameter_Passing_Mechanism_Specified
        (Typ : Entity_Id)
         return Boolean;
      --  Returns True if parameter-passing mechanism is specified for type Typ

      function May_Cause_Aliasing
        (Formal_1 : Entity_Id;
         Formal_2 : Entity_Id) return Boolean;
      --  Determine whether two formal parameters can alias each other
      --  depending on their modes.

      function Original_Actual (N : Node_Id) return Node_Id;
      --  The expander may replace an actual with a temporary for the sake of
      --  side effect removal. The temporary may hide a potential aliasing as
      --  it does not share the address of the actual. This routine attempts
      --  to retrieve the original actual.

      procedure Overlap_Check
        (Actual_1 : Node_Id;
         Actual_2 : Node_Id;
         Formal_1 : Entity_Id;
         Formal_2 : Entity_Id;
         Check    : in out Node_Id);
      --  Create a check to determine whether Actual_1 overlaps with Actual_2.
      --  If detailed exception messages are enabled, the check is augmented to
      --  provide information about the names of the corresponding formals. See
      --  the body for details. Actual_1 and Actual_2 denote the two actuals to
      --  be tested. Formal_1 and Formal_2 denote the corresponding formals.
      --  Check contains all and-ed simple tests generated so far or remains
      --  unchanged in the case of detailed exception messaged.

      -------------------------------------------
      -- Parameter_Passing_Mechanism_Specified --
      -------------------------------------------

      function Parameter_Passing_Mechanism_Specified
        (Typ : Entity_Id)
         return Boolean
      is
      begin
         return Is_Elementary_Type (Typ)
           or else Is_By_Reference_Type (Typ);
      end Parameter_Passing_Mechanism_Specified;

      ------------------------
      -- May_Cause_Aliasing --
      ------------------------

      function May_Cause_Aliasing
        (Formal_1 : Entity_Id;
         Formal_2 : Entity_Id) return Boolean
      is
      begin
         --  The following combination cannot lead to aliasing

         --     Formal 1    Formal 2
         --     IN          IN

         if Ekind (Formal_1) = E_In_Parameter
              and then
            Ekind (Formal_2) = E_In_Parameter
         then
            return False;

         --  The following combinations may lead to aliasing

         --     Formal 1    Formal 2
         --     IN          OUT
         --     IN          IN OUT
         --     OUT         IN
         --     OUT         IN OUT
         --     OUT         OUT

         else
            return True;
         end if;
      end May_Cause_Aliasing;

      ---------------------
      -- Original_Actual --
      ---------------------

      function Original_Actual (N : Node_Id) return Node_Id is
      begin
         if Nkind (N) = N_Type_Conversion then
            return Expression (N);

         --  The expander created a temporary to capture the result of a type
         --  conversion where the expression is the real actual.

         elsif Nkind (N) = N_Identifier
           and then Present (Original_Node (N))
           and then Nkind (Original_Node (N)) = N_Type_Conversion
         then
            return Expression (Original_Node (N));
         end if;

         return N;
      end Original_Actual;

      -------------------
      -- Overlap_Check --
      -------------------

      procedure Overlap_Check
        (Actual_1 : Node_Id;
         Actual_2 : Node_Id;
         Formal_1 : Entity_Id;
         Formal_2 : Entity_Id;
         Check    : in out Node_Id)
      is
         Cond        : Node_Id;
         Formal_Name : Bounded_String;

      begin
         --  Generate:
         --    Actual_1'Overlaps_Storage (Actual_2)

         Cond :=
           Make_Attribute_Reference (Loc,
             Prefix         => New_Copy_Tree (Original_Actual (Actual_1)),
             Attribute_Name => Name_Overlaps_Storage,
             Expressions    =>
               New_List (New_Copy_Tree (Original_Actual (Actual_2))));

         --  Generate the following check when detailed exception messages are
         --  enabled:

         --    if Actual_1'Overlaps_Storage (Actual_2) then
         --       raise Program_Error with <detailed message>;
         --    end if;

         if Exception_Extra_Info then
            Start_String;

            --  Do not generate location information for internal calls

            if Comes_From_Source (Call) then
               Store_String_Chars (Build_Location_String (Loc));
               Store_String_Char (' ');
            end if;

            Store_String_Chars ("aliased parameters, actuals for """);

            Append (Formal_Name, Chars (Formal_1));
            Adjust_Name_Case (Formal_Name, Sloc (Formal_1));
            Store_String_Chars (To_String (Formal_Name));

            Store_String_Chars (""" and """);

            Formal_Name.Length := 0;

            Append (Formal_Name, Chars (Formal_2));
            Adjust_Name_Case (Formal_Name, Sloc (Formal_2));
            Store_String_Chars (To_String (Formal_Name));

            Store_String_Chars (""" overlap");

            Insert_Action (Call,
              Make_If_Statement (Loc,
                Condition       => Cond,
                Then_Statements => New_List (
                  Make_Raise_Statement (Loc,
                    Name       =>
                      New_Occurrence_Of (Standard_Program_Error, Loc),
                    Expression => Make_String_Literal (Loc, End_String)))));

         --  Create a sequence of overlapping checks by and-ing them all
         --  together.

         else
            if No (Check) then
               Check := Cond;
            else
               Check :=
                 Make_And_Then (Loc,
                   Left_Opnd  => Check,
                   Right_Opnd => Cond);
            end if;
         end if;
      end Overlap_Check;

      --  Local variables

      Actual_1   : Node_Id;
      Actual_2   : Node_Id;
      Check      : Node_Id;
      Formal_1   : Entity_Id;
      Formal_2   : Entity_Id;
      Orig_Act_1 : Node_Id;
      Orig_Act_2 : Node_Id;

   --  Start of processing for Apply_Parameter_Aliasing_Checks

   begin
      Check := Empty;

      Actual_1 := First_Actual (Call);
      Formal_1 := First_Formal (Subp);
      while Present (Actual_1) and then Present (Formal_1) loop
         Orig_Act_1 := Original_Actual (Actual_1);

         if Is_Name_Reference (Orig_Act_1) then
            Actual_2 := Next_Actual (Actual_1);
            Formal_2 := Next_Formal (Formal_1);
            while Present (Actual_2) and then Present (Formal_2) loop
               Orig_Act_2 := Original_Actual (Actual_2);

               --  Generate the check only when the mode of the two formals may
               --  lead to aliasing.

               if Is_Name_Reference (Orig_Act_2)
                 and then May_Cause_Aliasing (Formal_1, Formal_2)
               then

                  --  The aliasing check only applies when some of the formals
                  --  have their passing mechanism unspecified; RM 6.2 (12/3).

                  if Parameter_Passing_Mechanism_Specified (Etype (Orig_Act_1))
                       and then
                     Parameter_Passing_Mechanism_Specified (Etype (Orig_Act_2))
                  then
                     null;
                  else
                     Remove_Side_Effects (Actual_1);
                     Remove_Side_Effects (Actual_2);

                     Overlap_Check
                       (Actual_1 => Actual_1,
                        Actual_2 => Actual_2,
                        Formal_1 => Formal_1,
                        Formal_2 => Formal_2,
                        Check    => Check);
                  end if;
               end if;

               Next_Actual (Actual_2);
               Next_Formal (Formal_2);
            end loop;
         end if;

         Next_Actual (Actual_1);
         Next_Formal (Formal_1);
      end loop;

      --  Place a simple check right before the call

      if Present (Check) and then not Exception_Extra_Info then
         Insert_Action (Call,
           Make_Raise_Program_Error (Loc,
             Condition => Check,
             Reason    => PE_Aliased_Parameters));
      end if;
   end Apply_Parameter_Aliasing_Checks;

   -------------------------------------
   -- Apply_Parameter_Validity_Checks --
   -------------------------------------

   procedure Apply_Parameter_Validity_Checks (Subp : Entity_Id) is
      Subp_Decl : Node_Id;

      procedure Add_Validity_Check
        (Formal     : Entity_Id;
         Prag_Nam   : Name_Id;
         For_Result : Boolean := False);
      --  Add a single 'Valid[_Scalars] check which verifies the initialization
      --  of Formal. Prag_Nam denotes the pre or post condition pragma name.
      --  Set flag For_Result when to verify the result of a function.

      ------------------------
      -- Add_Validity_Check --
      ------------------------

      procedure Add_Validity_Check
        (Formal     : Entity_Id;
         Prag_Nam   : Name_Id;
         For_Result : Boolean := False)
      is
         procedure Build_Pre_Post_Condition (Expr : Node_Id);
         --  Create a pre/postcondition pragma that tests expression Expr

         ------------------------------
         -- Build_Pre_Post_Condition --
         ------------------------------

         procedure Build_Pre_Post_Condition (Expr : Node_Id) is
            Loc   : constant Source_Ptr := Sloc (Subp);
            Decls : List_Id;
            Prag  : Node_Id;

         begin
            Prag :=
              Make_Pragma (Loc,
                Chars                        => Prag_Nam,
                Pragma_Argument_Associations => New_List (
                  Make_Pragma_Argument_Association (Loc,
                    Chars      => Name_Check,
                    Expression => Expr)));

            --  Add a message unless exception messages are suppressed

            if not Exception_Locations_Suppressed then
               Append_To (Pragma_Argument_Associations (Prag),
                 Make_Pragma_Argument_Association (Loc,
                   Chars      => Name_Message,
                   Expression =>
                     Make_String_Literal (Loc,
                       Strval => "failed "
                                 & Get_Name_String (Prag_Nam)
                                 & " from "
                                 & Build_Location_String (Loc))));
            end if;

            --  Insert the pragma in the tree

            if Nkind (Parent (Subp_Decl)) = N_Compilation_Unit then
               Add_Global_Declaration (Prag);
               Analyze (Prag);

            --  PPC pragmas associated with subprogram bodies must be inserted
            --  in the declarative part of the body.

            elsif Nkind (Subp_Decl) = N_Subprogram_Body then
               Decls := Declarations (Subp_Decl);

               if No (Decls) then
                  Decls := New_List;
                  Set_Declarations (Subp_Decl, Decls);
               end if;

               Prepend_To (Decls, Prag);
               Analyze (Prag);

            --  For subprogram declarations insert the PPC pragma right after
            --  the declarative node.

            else
               Insert_After_And_Analyze (Subp_Decl, Prag);
            end if;
         end Build_Pre_Post_Condition;

         --  Local variables

         Loc   : constant Source_Ptr := Sloc (Subp);
         Typ   : constant Entity_Id  := Etype (Formal);
         Check : Node_Id;
         Nam   : Name_Id;

      --  Start of processing for Add_Validity_Check

      begin
         --  For scalars, generate 'Valid test

         if Is_Scalar_Type (Typ) then
            Nam := Name_Valid;

         --  For any non-scalar with scalar parts, generate 'Valid_Scalars test

         elsif Scalar_Part_Present (Typ) then
            Nam := Name_Valid_Scalars;

         --  No test needed for other cases (no scalars to test)

         else
            return;
         end if;

         --  Step 1: Create the expression to verify the validity of the
         --  context.

         Check := New_Occurrence_Of (Formal, Loc);

         --  When processing a function result, use 'Result. Generate
         --    Context'Result

         if For_Result then
            Check :=
              Make_Attribute_Reference (Loc,
                Prefix         => Check,
                Attribute_Name => Name_Result);
         end if;

         --  Generate:
         --    Context['Result]'Valid[_Scalars]

         Check :=
           Make_Attribute_Reference (Loc,
             Prefix         => Check,
             Attribute_Name => Nam);

         --  Step 2: Create a pre or post condition pragma

         Build_Pre_Post_Condition (Check);
      end Add_Validity_Check;

      --  Local variables

      Formal    : Entity_Id;
      Subp_Spec : Node_Id;

   --  Start of processing for Apply_Parameter_Validity_Checks

   begin
      --  Extract the subprogram specification and declaration nodes

      Subp_Spec := Parent (Subp);

      if No (Subp_Spec) then
         return;
      end if;

      if Nkind (Subp_Spec) = N_Defining_Program_Unit_Name then
         Subp_Spec := Parent (Subp_Spec);
      end if;

      Subp_Decl := Parent (Subp_Spec);

      if not Comes_From_Source (Subp)

        --  Do not process formal subprograms because the corresponding actual
        --  will receive the proper checks when the instance is analyzed.

        or else Is_Formal_Subprogram (Subp)

        --  Do not process imported subprograms since pre and postconditions
        --  are never verified on routines coming from a different language.

        or else Is_Imported (Subp)
        or else Is_Intrinsic_Subprogram (Subp)

        --  The PPC pragmas generated by this routine do not correspond to
        --  source aspects, therefore they cannot be applied to abstract
        --  subprograms.

        or else Nkind (Subp_Decl) = N_Abstract_Subprogram_Declaration

        --  Do not consider subprogram renaminds because the renamed entity
        --  already has the proper PPC pragmas.

        or else Nkind (Subp_Decl) = N_Subprogram_Renaming_Declaration

        --  Do not process null procedures because there is no benefit of
        --  adding the checks to a no action routine.

        or else (Nkind (Subp_Spec) = N_Procedure_Specification
                  and then Null_Present (Subp_Spec))
      then
         return;
      end if;

      --  Inspect all the formals applying aliasing and scalar initialization
      --  checks where applicable.

      Formal := First_Formal (Subp);
      while Present (Formal) loop

         --  Generate the following scalar initialization checks for each
         --  formal parameter:

         --    mode IN     - Pre       => Formal'Valid[_Scalars]
         --    mode IN OUT - Pre, Post => Formal'Valid[_Scalars]
         --    mode    OUT -      Post => Formal'Valid[_Scalars]

         if Ekind (Formal) in E_In_Parameter | E_In_Out_Parameter then
            Add_Validity_Check (Formal, Name_Precondition, False);
         end if;

         if Ekind (Formal) in E_In_Out_Parameter | E_Out_Parameter then
            Add_Validity_Check (Formal, Name_Postcondition, False);
         end if;

         Next_Formal (Formal);
      end loop;

      --  Generate following scalar initialization check for function result:

      --    Post => Subp'Result'Valid[_Scalars]

      if Ekind (Subp) = E_Function then
         Add_Validity_Check (Subp, Name_Postcondition, True);
      end if;
   end Apply_Parameter_Validity_Checks;

   ---------------------------
   -- Apply_Predicate_Check --
   ---------------------------

   procedure Apply_Predicate_Check
     (N   : Node_Id;
      Typ : Entity_Id;
      Fun : Entity_Id := Empty)
   is
      Par : Node_Id;
      S   : Entity_Id;

      Check_Disabled : constant Boolean := (not Predicate_Enabled (Typ))
        or else not Predicate_Check_In_Scope (N);
   begin
      S := Current_Scope;
      while Present (S) and then not Is_Subprogram (S) loop
         S := Scope (S);
      end loop;

      --  If the check appears within the predicate function itself, it means
      --  that the user specified a check whose formal is the predicated
      --  subtype itself, rather than some covering type. This is likely to be
      --  a common error, and thus deserves a warning. We want to emit this
      --  warning even if predicate checking is disabled (in which case the
      --  warning is still useful even if it is not strictly accurate).

      if Present (S) and then S = Predicate_Function (Typ) then
         Error_Msg_NE
           ("predicate check includes a call to& that requires a "
            & "predicate check??", Parent (N), Fun);
         Error_Msg_N
           ("\this will result in infinite recursion??", Parent (N));

         if Is_First_Subtype (Typ) then
            Error_Msg_NE
              ("\use an explicit subtype of& to carry the predicate",
               Parent (N), Typ);
         end if;

         if not Check_Disabled then
            Insert_Action (N,
              Make_Raise_Storage_Error (Sloc (N),
                Reason => SE_Infinite_Recursion));
            return;
         end if;
      end if;

      if Check_Disabled then
         return;
      end if;

      --  Normal case of predicate active

      --  If the expression is an IN parameter, the predicate will have
      --  been applied at the point of call. An additional check would
      --  be redundant, or will lead to out-of-scope references if the
      --  call appears within an aspect specification for a precondition.

      --  However, if the reference is within the body of the subprogram
      --  that declares the formal, the predicate can safely be applied,
      --  which may be necessary for a nested call whose formal has a
      --  different predicate.

      if Is_Entity_Name (N)
        and then Ekind (Entity (N)) = E_In_Parameter
      then
         declare
            In_Body : Boolean := False;
            P       : Node_Id := Parent (N);

         begin
            while Present (P) loop
               if Nkind (P) = N_Subprogram_Body
                 and then
                   ((Present (Corresponding_Spec (P))
                      and then
                        Corresponding_Spec (P) = Scope (Entity (N)))
                      or else
                        Defining_Unit_Name (Specification (P)) =
                          Scope (Entity (N)))
               then
                  In_Body := True;
                  exit;
               end if;

               P := Parent (P);
            end loop;

            if not In_Body then
               return;
            end if;
         end;
      end if;

      --  If the type has a static predicate and the expression is known
      --  at compile time, see if the expression satisfies the predicate.

      Check_Expression_Against_Static_Predicate (N, Typ);

      if not Expander_Active then
         return;
      end if;

      Par := Parent (N);
      if Nkind (Par) = N_Qualified_Expression then
         Par := Parent (Par);
      end if;

      --  For an entity of the type, generate a call to the predicate
      --  function, unless its type is an actual subtype, which is not
      --  visible outside of the enclosing subprogram.

      if Is_Entity_Name (N)
        and then not Is_Actual_Subtype (Typ)
      then
         Insert_Action (N,
           Make_Predicate_Check
             (Typ, New_Occurrence_Of (Entity (N), Sloc (N))));
         return;

      elsif Nkind (N) in N_Aggregate | N_Extension_Aggregate then

         --  If the expression is an aggregate in an assignment, apply the
         --  check to the LHS after the assignment, rather than create a
         --  redundant temporary. This is only necessary in rare cases
         --  of array types (including strings) initialized with an
         --  aggregate with an "others" clause, either coming from source
         --  or generated by an Initialize_Scalars pragma.

         if Nkind (Par) = N_Assignment_Statement then
            Insert_Action_After (Par,
              Make_Predicate_Check
                (Typ, Duplicate_Subexpr (Name (Par))));
            return;

         --  Similarly, if the expression is an aggregate in an object
         --  declaration, apply it to the object after the declaration.
         --  This is only necessary in rare cases of tagged extensions
         --  initialized with an aggregate with an "others => <>" clause.

         elsif Nkind (Par) = N_Object_Declaration then
            Insert_Action_After (Par,
              Make_Predicate_Check (Typ,
                New_Occurrence_Of (Defining_Identifier (Par), Sloc (N))));
            return;
         end if;
      end if;

      --  If the expression is not an entity it may have side effects,
      --  and the following call will create an object declaration for
      --  it. We disable checks during its analysis, to prevent an
      --  infinite recursion.

      Insert_Action (N,
        Make_Predicate_Check
          (Typ, Duplicate_Subexpr (N)), Suppress => All_Checks);
   end Apply_Predicate_Check;

   -----------------------
   -- Apply_Range_Check --
   -----------------------

   procedure Apply_Range_Check
     (Expr        : Node_Id;
      Target_Typ  : Entity_Id;
      Source_Typ  : Entity_Id := Empty;
      Insert_Node : Node_Id   := Empty)
   is
      Checks_On : constant Boolean :=
                    not Index_Checks_Suppressed (Target_Typ)
                      or else
                    not Range_Checks_Suppressed (Target_Typ);

      Loc : constant Source_Ptr := Sloc (Expr);

      Cond     : Node_Id;
      R_Cno    : Node_Id;
      R_Result : Check_Result;

   begin
      --  Only apply checks when generating code. In GNATprove mode, we do not
      --  apply the checks, but we still call Selected_Range_Checks to possibly
      --  issue errors on SPARK code when a run-time error can be detected at
      --  compile time.

      if not GNATprove_Mode then
         if not Expander_Active or not Checks_On then
            return;
         end if;
      end if;

      R_Result :=
        Selected_Range_Checks (Expr, Target_Typ, Source_Typ, Insert_Node);

      if GNATprove_Mode then
         return;
      end if;

      for J in 1 .. 2 loop
         R_Cno := R_Result (J);
         exit when No (R_Cno);

         --  The range check requires runtime evaluation. Depending on what its
         --  triggering condition is, the check may be converted into a compile
         --  time constraint check.

         if Nkind (R_Cno) = N_Raise_Constraint_Error
           and then Present (Condition (R_Cno))
         then
            Cond := Condition (R_Cno);

            --  Insert the range check before the related context. Note that
            --  this action analyses the triggering condition.

            if Present (Insert_Node) then
               Insert_Action (Insert_Node, R_Cno);
            else
               Insert_Action (Expr, R_Cno);
            end if;

            --  The triggering condition evaluates to True, the range check
            --  can be converted into a compile time constraint check.

            if Is_Entity_Name (Cond)
              and then Entity (Cond) = Standard_True
            then
               --  Since an N_Range is technically not an expression, we have
               --  to set one of the bounds to C_E and then just flag the
               --  N_Range. The warning message will point to the lower bound
               --  and complain about a range, which seems OK.

               if Nkind (Expr) = N_Range then
                  Apply_Compile_Time_Constraint_Error
                    (Low_Bound (Expr),
                     "static range out of bounds of}??",
                     CE_Range_Check_Failed,
                     Ent => Target_Typ,
                     Typ => Target_Typ);

                  Set_Raises_Constraint_Error (Expr);

               else
                  Apply_Compile_Time_Constraint_Error
                    (Expr,
                     "static value out of range of}??",
                     CE_Range_Check_Failed,
                     Ent => Target_Typ,
                     Typ => Target_Typ);
               end if;
            end if;

         --  The range check raises Constraint_Error explicitly

         elsif Present (Insert_Node) then
            R_Cno :=
              Make_Raise_Constraint_Error (Sloc (Insert_Node),
                Reason => CE_Range_Check_Failed);

            Insert_Action (Insert_Node, R_Cno);

         else
            Install_Static_Check (R_Cno, Loc);
         end if;
      end loop;
   end Apply_Range_Check;

   ------------------------------
   -- Apply_Scalar_Range_Check --
   ------------------------------

   --  Note that Apply_Scalar_Range_Check never turns the Do_Range_Check flag
   --  off if it is already set on.

   procedure Apply_Scalar_Range_Check
     (Expr       : Node_Id;
      Target_Typ : Entity_Id;
      Source_Typ : Entity_Id := Empty;
      Fixed_Int  : Boolean   := False)
   is
      Parnt   : constant Node_Id := Parent (Expr);
      S_Typ   : Entity_Id;
      Arr     : Node_Id   := Empty;  -- initialize to prevent warning
      Arr_Typ : Entity_Id := Empty;  -- initialize to prevent warning

      Is_Subscr_Ref : Boolean;
      --  Set true if Expr is a subscript

      Is_Unconstrained_Subscr_Ref : Boolean;
      --  Set true if Expr is a subscript of an unconstrained array. In this
      --  case we do not attempt to do an analysis of the value against the
      --  range of the subscript, since we don't know the actual subtype.

      Int_Real : Boolean;
      --  Set to True if Expr should be regarded as a real value even though
      --  the type of Expr might be discrete.

      procedure Bad_Value (Warn : Boolean := False);
      --  Procedure called if value is determined to be out of range. Warn is
      --  True to force a warning instead of an error, even when SPARK_Mode is
      --  On.

      ---------------
      -- Bad_Value --
      ---------------

      procedure Bad_Value (Warn : Boolean := False) is
      begin
         Apply_Compile_Time_Constraint_Error
           (Expr, "value not in range of}??", CE_Range_Check_Failed,
            Ent  => Target_Typ,
            Typ  => Target_Typ,
            Warn => Warn);
      end Bad_Value;

   --  Start of processing for Apply_Scalar_Range_Check

   begin
      --  Return if check obviously not needed

      if
         --  Not needed inside generic

         Inside_A_Generic

         --  Not needed if previous error

         or else Target_Typ = Any_Type
         or else Nkind (Expr) = N_Error

         --  Not needed for non-scalar type

         or else not Is_Scalar_Type (Target_Typ)

         --  Not needed if we know node raises CE already

         or else Raises_Constraint_Error (Expr)
      then
         return;
      end if;

      --  Now, see if checks are suppressed

      Is_Subscr_Ref :=
        Is_List_Member (Expr) and then Nkind (Parnt) = N_Indexed_Component;

      if Is_Subscr_Ref then
         Arr := Prefix (Parnt);
         Arr_Typ := Get_Actual_Subtype_If_Available (Arr);

         if Is_Access_Type (Arr_Typ) then
            Arr_Typ := Designated_Type (Arr_Typ);
         end if;
      end if;

      if not Do_Range_Check (Expr) then

         --  Subscript reference. Check for Index_Checks suppressed

         if Is_Subscr_Ref then

            --  Check array type and its base type

            if Index_Checks_Suppressed (Arr_Typ)
              or else Index_Checks_Suppressed (Base_Type (Arr_Typ))
            then
               return;

            --  Check array itself if it is an entity name

            elsif Is_Entity_Name (Arr)
              and then Index_Checks_Suppressed (Entity (Arr))
            then
               return;

            --  Check expression itself if it is an entity name

            elsif Is_Entity_Name (Expr)
              and then Index_Checks_Suppressed (Entity (Expr))
            then
               return;
            end if;

         --  All other cases, check for Range_Checks suppressed

         else
            --  Check target type and its base type

            if Range_Checks_Suppressed (Target_Typ)
              or else Range_Checks_Suppressed (Base_Type (Target_Typ))
            then
               return;

            --  Check expression itself if it is an entity name

            elsif Is_Entity_Name (Expr)
              and then Range_Checks_Suppressed (Entity (Expr))
            then
               return;

            --  If Expr is part of an assignment statement, then check left
            --  side of assignment if it is an entity name.

            elsif Nkind (Parnt) = N_Assignment_Statement
              and then Is_Entity_Name (Name (Parnt))
              and then Range_Checks_Suppressed (Entity (Name (Parnt)))
            then
               return;
            end if;
         end if;
      end if;

      --  Do not set range checks if they are killed

      if Nkind (Expr) = N_Unchecked_Type_Conversion
        and then Kill_Range_Check (Expr)
      then
         return;
      end if;

      --  Do not set range checks for any values from System.Scalar_Values
      --  since the whole idea of such values is to avoid checking them.

      if Is_Entity_Name (Expr)
        and then Is_RTU (Scope (Entity (Expr)), System_Scalar_Values)
      then
         return;
      end if;

      --  Now see if we need a check

      if No (Source_Typ) then
         S_Typ := Etype (Expr);
      else
         S_Typ := Source_Typ;
      end if;

      if not Is_Scalar_Type (S_Typ) or else S_Typ = Any_Type then
         return;
      end if;

      Is_Unconstrained_Subscr_Ref :=
        Is_Subscr_Ref and then not Is_Constrained (Arr_Typ);

      --  Special checks for floating-point type

      if Is_Floating_Point_Type (S_Typ) then

         --  Always do a range check if the source type includes infinities and
         --  the target type does not include infinities. We do not do this if
         --  range checks are killed.
         --  If the expression is a literal and the bounds of the type are
         --  static constants it may be possible to optimize the check.

         if Has_Infinities (S_Typ)
           and then not Has_Infinities (Target_Typ)
         then
            --  If the expression is a literal and the bounds of the type are
            --  static constants it may be possible to optimize the check.

            if Nkind (Expr) = N_Real_Literal then
               declare
                  Tlo : constant Node_Id := Type_Low_Bound  (Target_Typ);
                  Thi : constant Node_Id := Type_High_Bound (Target_Typ);

               begin
                  if Compile_Time_Known_Value (Tlo)
                    and then Compile_Time_Known_Value (Thi)
                    and then Expr_Value_R (Expr) >= Expr_Value_R (Tlo)
                    and then Expr_Value_R (Expr) <= Expr_Value_R (Thi)
                  then
                     return;
                  else
                     Enable_Range_Check (Expr);
                  end if;
               end;

            else
               Enable_Range_Check (Expr);
            end if;
         end if;
      end if;

      --  Return if we know expression is definitely in the range of the target
      --  type as determined by Determine_Range_To_Discrete. Right now we only
      --  do this for discrete target types, i.e. neither for fixed-point nor
      --  for floating-point types. But the additional less precise tests below
      --  catch these cases.

      --  Note: skip this if we are given a source_typ, since the point of
      --  supplying a Source_Typ is to stop us looking at the expression.
      --  We could sharpen this test to be out parameters only ???

      if Is_Discrete_Type (Target_Typ)
        and then not Is_Unconstrained_Subscr_Ref
        and then No (Source_Typ)
      then
         declare
            Thi : constant Node_Id := Type_High_Bound (Target_Typ);
            Tlo : constant Node_Id := Type_Low_Bound  (Target_Typ);

         begin
            if Compile_Time_Known_Value (Tlo)
              and then Compile_Time_Known_Value (Thi)
            then
               declare
                  OK  : Boolean := False;  -- initialize to prevent warning
                  Hiv : constant Uint := Expr_Value (Thi);
                  Lov : constant Uint := Expr_Value (Tlo);
                  Hi  : Uint := No_Uint;
                  Lo  : Uint := No_Uint;

               begin
                  --  If range is null, we for sure have a constraint error (we
                  --  don't even need to look at the value involved, since all
                  --  possible values will raise CE).

                  if Lov > Hiv then

                     --  When SPARK_Mode is On, force a warning instead of
                     --  an error in that case, as this likely corresponds
                     --  to deactivated code.

                     Bad_Value (Warn => SPARK_Mode = On);

                     return;
                  end if;

                  --  Otherwise determine range of value

                  Determine_Range_To_Discrete
                    (Expr, OK, Lo, Hi, Fixed_Int, Assume_Valid => True);

                  if OK then

                     --  If definitely in range, all OK

                     if Lo >= Lov and then Hi <= Hiv then
                        return;

                     --  If definitely not in range, warn

                     elsif Lov > Hi or else Hiv < Lo then

                        --  Ignore out of range values for System.Priority in
                        --  CodePeer mode since the actual target compiler may
                        --  provide a wider range.

                        if not CodePeer_Mode
                          or else not Is_RTE (Target_Typ, RE_Priority)
                        then
                           Bad_Value;
                        end if;

                        return;

                     --  Otherwise we don't know

                     else
                        null;
                     end if;
                  end if;
               end;
            end if;
         end;
      end if;

      Int_Real :=
        Is_Floating_Point_Type (S_Typ)
          or else (Is_Fixed_Point_Type (S_Typ) and then not Fixed_Int);

      --  Check if we can determine at compile time whether Expr is in the
      --  range of the target type. Note that if S_Typ is within the bounds
      --  of Target_Typ then this must be the case. This check is meaningful
      --  only if this is not a conversion between integer and real types,
      --  unless for a fixed-point type if Fixed_Int is set.

      if not Is_Unconstrained_Subscr_Ref
        and then (Is_Discrete_Type (S_Typ) = Is_Discrete_Type (Target_Typ)
                   or else (Fixed_Int and then Is_Discrete_Type (Target_Typ)))
        and then
          (In_Subrange_Of (S_Typ, Target_Typ, Fixed_Int)

             --  Also check if the expression itself is in the range of the
             --  target type if it is a known at compile time value. We skip
             --  this test if S_Typ is set since for OUT and IN OUT parameters
             --  the Expr itself is not relevant to the checking.

             or else
               (No (Source_Typ)
                  and then Is_In_Range (Expr, Target_Typ,
                                        Assume_Valid => True,
                                        Fixed_Int    => Fixed_Int,
                                        Int_Real     => Int_Real)))
      then
         return;

      elsif Is_Out_Of_Range (Expr, Target_Typ,
                             Assume_Valid => True,
                             Fixed_Int    => Fixed_Int,
                             Int_Real     => Int_Real)
      then
         Bad_Value;
         return;

      --  Floating-point case
      --  In the floating-point case, we only do range checks if the type is
      --  constrained. We definitely do NOT want range checks for unconstrained
      --  types, since we want to have infinities, except when
      --  Check_Float_Overflow is set.

      elsif Is_Floating_Point_Type (S_Typ) then
         if Is_Constrained (S_Typ) or else Check_Float_Overflow then
            Enable_Range_Check (Expr);
         end if;

      --  For all other cases we enable a range check unconditionally

      else
         Enable_Range_Check (Expr);
         return;
      end if;
   end Apply_Scalar_Range_Check;

   ----------------------------------
   -- Apply_Selected_Length_Checks --
   ----------------------------------

   procedure Apply_Selected_Length_Checks
     (Expr       : Node_Id;
      Target_Typ : Entity_Id;
      Source_Typ : Entity_Id;
      Do_Static  : Boolean)
   is
      Checks_On : constant Boolean :=
                    not Index_Checks_Suppressed (Target_Typ)
                      or else
                    not Length_Checks_Suppressed (Target_Typ);

      Loc : constant Source_Ptr := Sloc (Expr);

      Cond     : Node_Id;
      R_Cno    : Node_Id;
      R_Result : Check_Result;

   begin
      --  Only apply checks when generating code

      --  Note: this means that we lose some useful warnings if the expander
      --  is not active.

      if not Expander_Active then
         return;
      end if;

      R_Result :=
        Selected_Length_Checks (Expr, Target_Typ, Source_Typ, Empty);

      for J in 1 .. 2 loop
         R_Cno := R_Result (J);
         exit when No (R_Cno);

         --  A length check may mention an Itype which is attached to a
         --  subsequent node. At the top level in a package this can cause
         --  an order-of-elaboration problem, so we make sure that the itype
         --  is referenced now.

         if Ekind (Current_Scope) = E_Package
           and then Is_Compilation_Unit (Current_Scope)
         then
            Ensure_Defined (Target_Typ, Expr);

            if Present (Source_Typ) then
               Ensure_Defined (Source_Typ, Expr);

            elsif Is_Itype (Etype (Expr)) then
               Ensure_Defined (Etype (Expr), Expr);
            end if;
         end if;

         if Nkind (R_Cno) = N_Raise_Constraint_Error
           and then Present (Condition (R_Cno))
         then
            Cond := Condition (R_Cno);

            --  Case where node does not now have a dynamic check

            if not Has_Dynamic_Length_Check (Expr) then

               --  If checks are on, just insert the check

               if Checks_On then
                  Insert_Action (Expr, R_Cno);

                  if not Do_Static then
                     Set_Has_Dynamic_Length_Check (Expr);
                  end if;

               --  If checks are off, then analyze the length check after
               --  temporarily attaching it to the tree in case the relevant
               --  condition can be evaluated at compile time. We still want a
               --  compile time warning in this case.

               else
                  Set_Parent (R_Cno, Expr);
                  Analyze (R_Cno);
               end if;
            end if;

            --  Output a warning if the condition is known to be True

            if Is_Entity_Name (Cond)
              and then Entity (Cond) = Standard_True
            then
               Apply_Compile_Time_Constraint_Error
                 (Expr, "wrong length for array of}??",
                  CE_Length_Check_Failed,
                  Ent => Target_Typ,
                  Typ => Target_Typ);

            --  If we were only doing a static check, or if checks are not
            --  on, then we want to delete the check, since it is not needed.
            --  We do this by replacing the if statement by a null statement

            elsif Do_Static or else not Checks_On then
               Remove_Warning_Messages (R_Cno);
               Rewrite (R_Cno, Make_Null_Statement (Loc));
            end if;

         else
            Install_Static_Check (R_Cno, Loc);
         end if;
      end loop;
   end Apply_Selected_Length_Checks;

   -------------------------------
   -- Apply_Static_Length_Check --
   -------------------------------

   procedure Apply_Static_Length_Check
     (Expr       : Node_Id;
      Target_Typ : Entity_Id;
      Source_Typ : Entity_Id := Empty)
   is
   begin
      Apply_Selected_Length_Checks
        (Expr, Target_Typ, Source_Typ, Do_Static => True);
   end Apply_Static_Length_Check;

   -------------------------------------
   -- Apply_Subscript_Validity_Checks --
   -------------------------------------

   procedure Apply_Subscript_Validity_Checks
     (Expr            : Node_Id;
      No_Check_Needed : Dimension_Set := Empty_Dimension_Set) is
      Sub : Node_Id;

      Dimension : Pos := 1;
   begin
      pragma Assert (Nkind (Expr) = N_Indexed_Component);

      --  Loop through subscripts

      Sub := First (Expressions (Expr));
      while Present (Sub) loop

         --  Check one subscript. Note that we do not worry about enumeration
         --  type with holes, since we will convert the value to a Pos value
         --  for the subscript, and that convert will do the necessary validity
         --  check.

         if (No_Check_Needed = Empty_Dimension_Set)
           or else not No_Check_Needed.Elements (Dimension)
         then
            Ensure_Valid (Sub, Holes_OK => True);
         end if;

         --  Move to next subscript

         Next (Sub);
         Dimension := Dimension + 1;
      end loop;
   end Apply_Subscript_Validity_Checks;

   ----------------------------------
   -- Apply_Type_Conversion_Checks --
   ----------------------------------

   procedure Apply_Type_Conversion_Checks (N : Node_Id) is
      Target_Type : constant Entity_Id := Etype (N);
      Target_Base : constant Entity_Id := Base_Type (Target_Type);
      Expr        : constant Node_Id   := Expression (N);

      Expr_Type : constant Entity_Id := Underlying_Type (Etype (Expr));
      --  Note: if Etype (Expr) is a private type without discriminants, its
      --  full view might have discriminants with defaults, so we need the
      --  full view here to retrieve the constraints.

      procedure Make_Discriminant_Constraint_Check
        (Target_Type : Entity_Id;
         Expr_Type   : Entity_Id);
      --  Generate a discriminant check based on the target type and expression
      --  type for Expr.

      ----------------------------------------
      -- Make_Discriminant_Constraint_Check --
      ----------------------------------------

      procedure Make_Discriminant_Constraint_Check
        (Target_Type : Entity_Id;
         Expr_Type   : Entity_Id)
      is
         Loc         : constant Source_Ptr := Sloc (N);
         Cond        : Node_Id;
         Constraint  : Elmt_Id;
         Discr_Value : Node_Id;
         Discr       : Entity_Id;

         New_Constraints : constant Elist_Id := New_Elmt_List;
         Old_Constraints : constant Elist_Id :=
           Discriminant_Constraint (Expr_Type);

      begin
         --  Build an actual discriminant constraint list using the stored
         --  constraint, to verify that the expression of the parent type
         --  satisfies the constraints imposed by the (unconstrained) derived
         --  type. This applies to value conversions, not to view conversions
         --  of tagged types.

         Constraint := First_Elmt (Stored_Constraint (Target_Type));
         while Present (Constraint) loop
            Discr_Value := Node (Constraint);

            if Is_Entity_Name (Discr_Value)
              and then Ekind (Entity (Discr_Value)) = E_Discriminant
            then
               Discr := Corresponding_Discriminant (Entity (Discr_Value));

               if Present (Discr)
                 and then Scope (Discr) = Base_Type (Expr_Type)
               then
                  --  Parent is constrained by new discriminant. Obtain
                  --  Value of original discriminant in expression. If the
                  --  new discriminant has been used to constrain more than
                  --  one of the stored discriminants, this will provide the
                  --  required consistency check.

                  Append_Elmt
                    (Make_Selected_Component (Loc,
                       Prefix        =>
                         Duplicate_Subexpr_No_Checks
                           (Expr, Name_Req => True),
                       Selector_Name =>
                         Make_Identifier (Loc, Chars (Discr))),
                     New_Constraints);

               else
                  --  Discriminant of more remote ancestor ???

                  return;
               end if;

            --  Derived type definition has an explicit value for this
            --  stored discriminant.

            else
               Append_Elmt
                 (Duplicate_Subexpr_No_Checks (Discr_Value),
                  New_Constraints);
            end if;

            Next_Elmt (Constraint);
         end loop;

         --  Use the unconstrained expression type to retrieve the
         --  discriminants of the parent, and apply momentarily the
         --  discriminant constraint synthesized above.

         --  Note: We use Expr_Type instead of Target_Type since the number of
         --  actual discriminants may be different due to the presence of
         --  stored discriminants and cause Build_Discriminant_Checks to fail.

         Set_Discriminant_Constraint (Expr_Type, New_Constraints);
         Cond := Build_Discriminant_Checks (Expr, Expr_Type);
         Set_Discriminant_Constraint (Expr_Type, Old_Constraints);

         --  Conversion between access types requires that we check for null
         --  before checking discriminants.

         if Is_Access_Type (Etype (Expr)) then
            Cond := Make_And_Then (Loc,
                      Left_Opnd  =>
                        Make_Op_Ne (Loc,
                          Left_Opnd  =>
                            Duplicate_Subexpr_No_Checks
                              (Expr, Name_Req => True),
                          Right_Opnd => Make_Null (Loc)),
                      Right_Opnd => Cond);
         end if;

         Insert_Action (N,
           Make_Raise_Constraint_Error (Loc,
             Condition => Cond,
             Reason    => CE_Discriminant_Check_Failed));
      end Make_Discriminant_Constraint_Check;

   --  Start of processing for Apply_Type_Conversion_Checks

   begin
      if Inside_A_Generic then
         return;

      --  Skip these checks if serious errors detected, there are some nasty
      --  situations of incomplete trees that blow things up.

      elsif Serious_Errors_Detected > 0 then
         return;

      --  Never generate discriminant checks for Unchecked_Union types

      elsif Present (Expr_Type)
        and then Is_Unchecked_Union (Expr_Type)
      then
         return;

      --  Scalar type conversions of the form Target_Type (Expr) require a
      --  range check if we cannot be sure that Expr is in the base type of
      --  Target_Typ and also that Expr is in the range of Target_Typ. These
      --  are not quite the same condition from an implementation point of
      --  view, but clearly the second includes the first.

      elsif Is_Scalar_Type (Target_Type) then
         declare
            Conv_OK : constant Boolean := Conversion_OK (N);
            --  If the Conversion_OK flag on the type conversion is set and no
            --  floating-point type is involved in the type conversion then
            --  fixed-point values must be read as integral values.

            Float_To_Int : constant Boolean :=
              Is_Floating_Point_Type (Expr_Type)
              and then Is_Integer_Type (Target_Type);

         begin
            if not Overflow_Checks_Suppressed (Target_Base)
              and then not Overflow_Checks_Suppressed (Target_Type)
              and then not
                In_Subrange_Of (Expr_Type, Target_Base, Fixed_Int => Conv_OK)
              and then not Float_To_Int
            then
               --  A small optimization: the attribute 'Pos applied to an
               --  enumeration type has a known range, even though its type is
               --  Universal_Integer. So in numeric conversions it is usually
               --  within range of the target integer type. Use the static
               --  bounds of the base types to check. Disable this optimization
               --  in case of a generic formal discrete type, because we don't
               --  necessarily know the upper bound yet.

               if Nkind (Expr) = N_Attribute_Reference
                 and then Attribute_Name (Expr) = Name_Pos
                 and then Is_Enumeration_Type (Etype (Prefix (Expr)))
                 and then not Is_Generic_Type (Etype (Prefix (Expr)))
                 and then Is_Integer_Type (Target_Type)
               then
                  declare
                     Enum_T : constant Entity_Id :=
                                Root_Type (Etype (Prefix (Expr)));
                     Int_T  : constant Entity_Id := Base_Type (Target_Type);
                     Last_I : constant Uint      :=
                                Intval (High_Bound (Scalar_Range (Int_T)));
                     Last_E : Uint;

                  begin
                     --  Character types have no explicit literals, so we use
                     --  the known number of characters in the type.

                     if Root_Type (Enum_T) = Standard_Character then
                        Last_E := UI_From_Int (255);

                     elsif Enum_T = Standard_Wide_Character
                       or else Enum_T = Standard_Wide_Wide_Character
                     then
                        Last_E := UI_From_Int (65535);

                     else
                        Last_E :=
                          Enumeration_Pos
                            (Entity (High_Bound (Scalar_Range (Enum_T))));
                     end if;

                     if Last_E > Last_I then
                        Activate_Overflow_Check (N);
                     end if;
                  end;
               else
                  Activate_Overflow_Check (N);
               end if;
            end if;

            if not Range_Checks_Suppressed (Target_Type)
              and then not Range_Checks_Suppressed (Expr_Type)
            then
               if Float_To_Int
                 and then not GNATprove_Mode
               then
                  Apply_Float_Conversion_Check (Expr, Target_Type);
               else
                  --  Raw conversions involving fixed-point types are expanded
                  --  separately and do not need a Range_Check flag yet, except
                  --  in GNATprove_Mode where this expansion is not performed.
                  --  This does not apply to conversion where fixed-point types
                  --  are treated as integers, which are precisely generated by
                  --  this expansion.

                  if GNATprove_Mode
                    or else Conv_OK
                    or else (not Is_Fixed_Point_Type (Expr_Type)
                              and then not Is_Fixed_Point_Type (Target_Type))
                  then
                     Apply_Scalar_Range_Check
                       (Expr, Target_Type, Fixed_Int => Conv_OK);

                  else
                     Set_Do_Range_Check (Expr, False);
                  end if;

                  --  If the target type has predicates, we need to indicate
                  --  the need for a check, even if Determine_Range finds that
                  --  the value is within bounds. This may be the case e.g for
                  --  a division with a constant denominator.

                  if Has_Predicates (Target_Type) then
                     Enable_Range_Check (Expr);
                  end if;
               end if;
            end if;
         end;

      --  Generate discriminant constraint checks for access types on the
      --  designated target type's stored constraints.

      --  Do we need to generate subtype predicate checks here as well ???

      elsif Comes_From_Source (N)
        and then Ekind (Target_Type) = E_General_Access_Type

        --  Check that both of the designated types have known discriminants,
        --  and that such checks on the target type are not suppressed.

        and then Has_Discriminants (Directly_Designated_Type (Target_Type))
        and then Has_Discriminants (Directly_Designated_Type (Expr_Type))
        and then not Discriminant_Checks_Suppressed
                       (Directly_Designated_Type (Target_Type))

        --  Verify the designated type of the target has stored constraints

        and then Present
                   (Stored_Constraint (Directly_Designated_Type (Target_Type)))
      then
         Make_Discriminant_Constraint_Check
           (Target_Type => Directly_Designated_Type (Target_Type),
            Expr_Type   => Directly_Designated_Type (Expr_Type));

      --  Create discriminant checks for the Target_Type's stored constraints

      elsif Comes_From_Source (N)
        and then not Discriminant_Checks_Suppressed (Target_Type)
        and then Is_Record_Type (Target_Type)
        and then Is_Derived_Type (Target_Type)
        and then not Is_Tagged_Type (Target_Type)
        and then not Is_Constrained (Target_Type)
        and then Present (Stored_Constraint (Target_Type))
      then
         Make_Discriminant_Constraint_Check (Target_Type, Expr_Type);

      --  For arrays, checks are set now, but conversions are applied during
      --  expansion, to take into accounts changes of representation. The
      --  checks become range checks on the base type or length checks on the
      --  subtype, depending on whether the target type is unconstrained or
      --  constrained. Note that the range check is put on the expression of a
      --  type conversion, while the length check is put on the type conversion
      --  itself.

      elsif Is_Array_Type (Target_Type) then
         if Is_Constrained (Target_Type) then
            Set_Do_Length_Check (N);
         else
            Set_Do_Range_Check (Expr);
         end if;
      end if;
   end Apply_Type_Conversion_Checks;

   ----------------------------------------------
   -- Apply_Universal_Integer_Attribute_Checks --
   ----------------------------------------------

   procedure Apply_Universal_Integer_Attribute_Checks (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id  := Etype (N);

   begin
      if Inside_A_Generic then
         return;

      --  Nothing to do if the result type is universal integer

      elsif Typ = Universal_Integer then
         return;

      --  Nothing to do if checks are suppressed

      elsif Range_Checks_Suppressed (Typ)
        and then Overflow_Checks_Suppressed (Typ)
      then
         return;

      --  Nothing to do if the attribute does not come from source. The
      --  internal attributes we generate of this type do not need checks,
      --  and furthermore the attempt to check them causes some circular
      --  elaboration orders when dealing with packed types.

      elsif not Comes_From_Source (N) then
         return;

      --  If the prefix is a selected component that depends on a discriminant
      --  the check may improperly expose a discriminant instead of using
      --  the bounds of the object itself. Set the type of the attribute to
      --  the base type of the context, so that a check will be imposed when
      --  needed (e.g. if the node appears as an index).

      elsif Nkind (Prefix (N)) = N_Selected_Component
        and then Ekind (Typ) = E_Signed_Integer_Subtype
        and then Depends_On_Discriminant (Scalar_Range (Typ))
      then
         Set_Etype (N, Base_Type (Typ));

      --  Otherwise, replace the attribute node with a type conversion node
      --  whose expression is the attribute, retyped to universal integer, and
      --  whose subtype mark is the target type. The call to analyze this
      --  conversion will set range and overflow checks as required for proper
      --  detection of an out of range value.

      else
         Set_Etype    (N, Universal_Integer);
         Set_Analyzed (N, True);

         Rewrite (N,
           Make_Type_Conversion (Loc,
             Subtype_Mark => New_Occurrence_Of (Typ, Loc),
             Expression   => Relocate_Node (N)));

         Analyze_And_Resolve (N, Typ);
         return;
      end if;
   end Apply_Universal_Integer_Attribute_Checks;

   -------------------------------------
   -- Atomic_Synchronization_Disabled --
   -------------------------------------

   --  Note: internally Disable/Enable_Atomic_Synchronization is implemented
   --  using a bogus check called Atomic_Synchronization. This is to make it
   --  more convenient to get exactly the same semantics as [Un]Suppress.

   function Atomic_Synchronization_Disabled (E : Entity_Id) return Boolean is
   begin
      --  If debug flag d.e is set, always return False, i.e. all atomic sync
      --  looks enabled, since it is never disabled.

      if Debug_Flag_Dot_E then
         return False;

      --  If debug flag d.d is set then always return True, i.e. all atomic
      --  sync looks disabled, since it always tests True.

      elsif Debug_Flag_Dot_D then
         return True;

      --  If entity present, then check result for that entity

      elsif Present (E) and then Checks_May_Be_Suppressed (E) then
         return Is_Check_Suppressed (E, Atomic_Synchronization);

      --  Otherwise result depends on current scope setting

      else
         return Scope_Suppress.Suppress (Atomic_Synchronization);
      end if;
   end Atomic_Synchronization_Disabled;

   -------------------------------
   -- Build_Discriminant_Checks --
   -------------------------------

   function Build_Discriminant_Checks
     (N     : Node_Id;
      T_Typ : Entity_Id) return Node_Id
   is
      Loc      : constant Source_Ptr := Sloc (N);
      Cond     : Node_Id;
      Disc     : Elmt_Id;
      Disc_Ent : Entity_Id;
      Dref     : Node_Id;
      Dval     : Node_Id;

      function Aggregate_Discriminant_Val (Disc : Entity_Id) return Node_Id;

      function Replace_Current_Instance
        (N : Node_Id) return Traverse_Result;
      --  Replace a reference to the current instance of the type with the
      --  corresponding _init formal of the initialization procedure. Note:
      --  this function relies on us currently being within the initialization
      --  procedure.

      --------------------------------
      -- Aggregate_Discriminant_Val --
      --------------------------------

      function Aggregate_Discriminant_Val (Disc : Entity_Id) return Node_Id is
         Assoc : Node_Id;

      begin
         --  The aggregate has been normalized with named associations. We use
         --  the Chars field to locate the discriminant to take into account
         --  discriminants in derived types, which carry the same name as those
         --  in the parent.

         Assoc := First (Component_Associations (N));
         while Present (Assoc) loop
            if Chars (First (Choices (Assoc))) = Chars (Disc) then
               return Expression (Assoc);
            else
               Next (Assoc);
            end if;
         end loop;

         --  Discriminant must have been found in the loop above

         raise Program_Error;
      end Aggregate_Discriminant_Val;

      ------------------------------
      -- Replace_Current_Instance --
      ------------------------------

      function Replace_Current_Instance
        (N : Node_Id) return Traverse_Result is
      begin
         if Is_Entity_Name (N)
           and then Etype (N) = Entity (N)
         then
            Rewrite (N,
              New_Occurrence_Of (First_Formal (Current_Subprogram), Loc));
         end if;

         return OK;
      end Replace_Current_Instance;

      procedure Search_And_Replace_Current_Instance is new
        Traverse_Proc (Replace_Current_Instance);

   --  Start of processing for Build_Discriminant_Checks

   begin
      --  Loop through discriminants evolving the condition

      Cond := Empty;
      Disc := First_Elmt (Discriminant_Constraint (T_Typ));

      --  For a fully private type, use the discriminants of the parent type

      if Is_Private_Type (T_Typ)
        and then No (Full_View (T_Typ))
      then
         Disc_Ent := First_Discriminant (Etype (Base_Type (T_Typ)));
      else
         Disc_Ent := First_Discriminant (T_Typ);
      end if;

      while Present (Disc) loop
         Dval := Node (Disc);

         if Nkind (Dval) = N_Identifier
           and then Ekind (Entity (Dval)) = E_Discriminant
         then
            Dval := New_Occurrence_Of (Discriminal (Entity (Dval)), Loc);
         else
            Dval := Duplicate_Subexpr_No_Checks (Dval);
         end if;

         --  Replace references to the current instance of the type with the
         --  corresponding _init formal of the initialization procedure.

         if Within_Init_Proc then
            Search_And_Replace_Current_Instance (Dval);
         end if;

         --  If we have an Unchecked_Union node, we can infer the discriminants
         --  of the node.

         if Is_Unchecked_Union (Base_Type (T_Typ)) then
            Dref := New_Copy (
              Get_Discriminant_Value (
                First_Discriminant (T_Typ),
                T_Typ,
                Stored_Constraint (T_Typ)));

         elsif Nkind (N) = N_Aggregate then
            Dref :=
               Duplicate_Subexpr_No_Checks
                 (Aggregate_Discriminant_Val (Disc_Ent));

         elsif Is_Access_Type (Etype (N)) then
            Dref :=
              Make_Selected_Component (Loc,
                Prefix        =>
                  Make_Explicit_Dereference (Loc,
                    Duplicate_Subexpr_No_Checks (N, Name_Req => True)),
                Selector_Name => Make_Identifier (Loc, Chars (Disc_Ent)));

            Set_Is_In_Discriminant_Check (Dref);
         else
            Dref :=
              Make_Selected_Component (Loc,
                Prefix        =>
                  Duplicate_Subexpr_No_Checks (N, Name_Req => True),
                Selector_Name => Make_Identifier (Loc, Chars (Disc_Ent)));

            Set_Is_In_Discriminant_Check (Dref);
         end if;

         Evolve_Or_Else (Cond,
           Make_Op_Ne (Loc,
             Left_Opnd  => Dref,
             Right_Opnd => Dval));

         Next_Elmt (Disc);
         Next_Discriminant (Disc_Ent);
      end loop;

      return Cond;
   end Build_Discriminant_Checks;

   ------------------
   -- Check_Needed --
   ------------------

   function Check_Needed (Nod : Node_Id; Check : Check_Type) return Boolean is
      N : Node_Id;
      P : Node_Id;
      K : Node_Kind;
      L : Node_Id;
      R : Node_Id;

      function Left_Expression (Op : Node_Id) return Node_Id;
      --  Return the relevant expression from the left operand of the given
      --  short circuit form: this is LO itself, except if LO is a qualified
      --  expression, a type conversion, or an expression with actions, in
      --  which case this is Left_Expression (Expression (LO)).

      ---------------------
      -- Left_Expression --
      ---------------------

      function Left_Expression (Op : Node_Id) return Node_Id is
         LE : Node_Id := Left_Opnd (Op);
      begin
         while Nkind (LE) in N_Qualified_Expression
                           | N_Type_Conversion
                           | N_Expression_With_Actions
         loop
            LE := Expression (LE);
         end loop;

         return LE;
      end Left_Expression;

   --  Start of processing for Check_Needed

   begin
      --  Always check if not simple entity

      if Nkind (Nod) not in N_Has_Entity
        or else not Comes_From_Source (Nod)
      then
         return True;
      end if;

      --  Look up tree for short circuit

      N := Nod;
      loop
         P := Parent (N);
         K := Nkind (P);

         --  Done if out of subexpression (note that we allow generated stuff
         --  such as itype declarations in this context, to keep the loop going
         --  since we may well have generated such stuff in complex situations.
         --  Also done if no parent (probably an error condition, but no point
         --  in behaving nasty if we find it).

         if No (P)
           or else (K not in N_Subexpr and then Comes_From_Source (P))
         then
            return True;

         --  Or/Or Else case, where test is part of the right operand, or is
         --  part of one of the actions associated with the right operand, and
         --  the left operand is an equality test.

         elsif K = N_Op_Or then
            exit when N = Right_Opnd (P)
              and then Nkind (Left_Expression (P)) = N_Op_Eq;

         elsif K = N_Or_Else then
            exit when (N = Right_Opnd (P)
                        or else
                          (Is_List_Member (N)
                             and then List_Containing (N) = Actions (P)))
              and then Nkind (Left_Expression (P)) = N_Op_Eq;

         --  Similar test for the And/And then case, where the left operand
         --  is an inequality test.

         elsif K = N_Op_And then
            exit when N = Right_Opnd (P)
              and then Nkind (Left_Expression (P)) = N_Op_Ne;

         elsif K = N_And_Then then
            exit when (N = Right_Opnd (P)
                        or else
                          (Is_List_Member (N)
                            and then List_Containing (N) = Actions (P)))
              and then Nkind (Left_Expression (P)) = N_Op_Ne;
         end if;

         N := P;
      end loop;

      --  If we fall through the loop, then we have a conditional with an
      --  appropriate test as its left operand, so look further.

      L := Left_Expression (P);

      --  L is an "=" or "/=" operator: extract its operands

      R := Right_Opnd (L);
      L := Left_Opnd (L);

      --  Left operand of test must match original variable

      if Nkind (L) not in N_Has_Entity or else Entity (L) /= Entity (Nod) then
         return True;
      end if;

      --  Right operand of test must be key value (zero or null)

      case Check is
         when Access_Check =>
            if not Known_Null (R) then
               return True;
            end if;

         when Division_Check =>
            if not Compile_Time_Known_Value (R)
              or else Expr_Value (R) /= Uint_0
            then
               return True;
            end if;

         when others =>
            raise Program_Error;
      end case;

      --  Here we have the optimizable case, warn if not short-circuited

      if K = N_Op_And or else K = N_Op_Or then
         Error_Msg_Warn := SPARK_Mode /= On;

         case Check is
            when Access_Check =>
               if GNATprove_Mode then
                  Error_Msg_N
                    ("Constraint_Error might have been raised (access check)",
                     Parent (Nod));
               else
                  Error_Msg_N
                    ("Constraint_Error may be raised (access check)??",
                     Parent (Nod));
               end if;

            when Division_Check =>
               if GNATprove_Mode then
                  Error_Msg_N
                    ("Constraint_Error might have been raised (zero divide)",
                     Parent (Nod));
               else
                  Error_Msg_N
                    ("Constraint_Error may be raised (zero divide)??",
                     Parent (Nod));
               end if;

            when others =>
               raise Program_Error;
         end case;

         if K = N_Op_And then
            Error_Msg_N -- CODEFIX
              ("use `AND THEN` instead of AND??", P);
         else
            Error_Msg_N -- CODEFIX
              ("use `OR ELSE` instead of OR??", P);
         end if;

         --  If not short-circuited, we need the check

         return True;

      --  If short-circuited, we can omit the check

      else
         return False;
      end if;
   end Check_Needed;

   -----------------------------------
   -- Check_Valid_Lvalue_Subscripts --
   -----------------------------------

   procedure Check_Valid_Lvalue_Subscripts (Expr : Node_Id) is
   begin
      --  Skip this if range checks are suppressed

      if Range_Checks_Suppressed (Etype (Expr)) then
         return;

      --  Only do this check for expressions that come from source. We assume
      --  that expander generated assignments explicitly include any necessary
      --  checks. Note that this is not just an optimization, it avoids
      --  infinite recursions.

      elsif not Comes_From_Source (Expr) then
         return;

      --  For a selected component, check the prefix

      elsif Nkind (Expr) = N_Selected_Component then
         Check_Valid_Lvalue_Subscripts (Prefix (Expr));
         return;

      --  Case of indexed component

      elsif Nkind (Expr) = N_Indexed_Component then
         Apply_Subscript_Validity_Checks (Expr);

         --  Prefix may itself be or contain an indexed component, and these
         --  subscripts need checking as well.

         Check_Valid_Lvalue_Subscripts (Prefix (Expr));
      end if;
   end Check_Valid_Lvalue_Subscripts;

   ----------------------------------
   -- Null_Exclusion_Static_Checks --
   ----------------------------------

   procedure Null_Exclusion_Static_Checks
     (N          : Node_Id;
      Comp       : Node_Id := Empty;
      Array_Comp : Boolean := False)
   is
      Has_Null  : constant Boolean   := Has_Null_Exclusion (N);
      Kind      : constant Node_Kind := Nkind (N);
      Error_Nod : Node_Id;
      Expr      : Node_Id;
      Typ       : Entity_Id;

   begin
      pragma Assert
        (Kind in N_Component_Declaration
               | N_Discriminant_Specification
               | N_Function_Specification
               | N_Object_Declaration
               | N_Parameter_Specification);

      if Kind = N_Function_Specification then
         Typ := Etype (Defining_Entity (N));
      else
         Typ := Etype (Defining_Identifier (N));
      end if;

      case Kind is
         when N_Component_Declaration =>
            if Present (Access_Definition (Component_Definition (N))) then
               Error_Nod := Component_Definition (N);
            else
               Error_Nod := Subtype_Indication (Component_Definition (N));
            end if;

         when N_Discriminant_Specification =>
            Error_Nod := Discriminant_Type (N);

         when N_Function_Specification =>
            Error_Nod := Result_Definition (N);

         when N_Object_Declaration =>
            Error_Nod := Object_Definition (N);

         when N_Parameter_Specification =>
            Error_Nod := Parameter_Type (N);

         when others =>
            raise Program_Error;
      end case;

      if Has_Null then

         --  Enforce legality rule 3.10 (13): A null exclusion can only be
         --  applied to an access [sub]type.

         if not Is_Access_Type (Typ) then
            Error_Msg_N
              ("`NOT NULL` allowed only for an access type", Error_Nod);

         --  Enforce legality rule RM 3.10(14/1): A null exclusion can only
         --  be applied to a [sub]type that does not exclude null already.

         elsif Can_Never_Be_Null (Typ) and then Comes_From_Source (Typ) then
            Error_Msg_NE
              ("`NOT NULL` not allowed (& already excludes null)",
               Error_Nod, Typ);
         end if;
      end if;

      --  Check that null-excluding objects are always initialized, except for
      --  deferred constants, for which the expression will appear in the full
      --  declaration.

      if Kind = N_Object_Declaration
        and then No (Expression (N))
        and then not Constant_Present (N)
        and then not No_Initialization (N)
      then
         if Present (Comp) then

            --  Specialize the warning message to indicate that we are dealing
            --  with an uninitialized composite object that has a defaulted
            --  null-excluding component.

            Error_Msg_Name_1 := Chars (Defining_Identifier (Comp));
            Error_Msg_Name_2 := Chars (Defining_Identifier (N));

            Discard_Node
              (Compile_Time_Constraint_Error
                 (N      => N,
                  Msg    =>
                    "(Ada 2005) null-excluding component % of object % must "
                    & "be initialized??",
                  Ent => Defining_Identifier (Comp)));

         --  This is a case of an array with null-excluding components, so
         --  indicate that in the warning.

         elsif Array_Comp then
            Discard_Node
              (Compile_Time_Constraint_Error
                 (N      => N,
                  Msg    =>
                    "(Ada 2005) null-excluding array components must "
                    & "be initialized??",
                  Ent => Defining_Identifier (N)));

         --  Normal case of object of a null-excluding access type

         else
            --  Add an expression that assigns null. This node is needed by
            --  Apply_Compile_Time_Constraint_Error, which will replace this
            --  with a Constraint_Error node.

            Set_Expression (N, Make_Null (Sloc (N)));
            Set_Etype (Expression (N), Etype (Defining_Identifier (N)));

            Apply_Compile_Time_Constraint_Error
              (N      => Expression (N),
               Msg    =>
                 "(Ada 2005) null-excluding objects must be initialized??",
               Reason => CE_Null_Not_Allowed);
         end if;
      end if;

      --  Check that a null-excluding component, formal or object is not being
      --  assigned a null value. Otherwise generate a warning message and
      --  replace Expression (N) by an N_Constraint_Error node.

      if Kind /= N_Function_Specification then
         Expr := Expression (N);

         if Present (Expr) and then Known_Null (Expr) then
            case Kind is
               when N_Component_Declaration
                  | N_Discriminant_Specification
               =>
                  Apply_Compile_Time_Constraint_Error
                    (N      => Expr,
                     Msg    =>
                       "(Ada 2005) NULL not allowed in null-excluding "
                       & "components??",
                     Reason => CE_Null_Not_Allowed);

               when N_Object_Declaration =>
                  Apply_Compile_Time_Constraint_Error
                    (N      => Expr,
                     Msg    =>
                       "(Ada 2005) NULL not allowed in null-excluding "
                       & "objects??",
                     Reason => CE_Null_Not_Allowed);

               when N_Parameter_Specification =>
                  Apply_Compile_Time_Constraint_Error
                    (N      => Expr,
                     Msg    =>
                       "(Ada 2005) NULL not allowed in null-excluding "
                       & "formals??",
                     Reason => CE_Null_Not_Allowed);

               when others =>
                  null;
            end case;
         end if;
      end if;
   end Null_Exclusion_Static_Checks;

   -------------------------------------
   -- Compute_Range_For_Arithmetic_Op --
   -------------------------------------

   procedure Compute_Range_For_Arithmetic_Op
     (Op       : Node_Kind;
      Lo_Left  : Uint;
      Hi_Left  : Uint;
      Lo_Right : Uint;
      Hi_Right : Uint;
      OK       : out Boolean;
      Lo       : out Uint;
      Hi       : out Uint)
   is
      --  Use local variables for possible adjustments

      Llo : Uint renames Lo_Left;
      Lhi : Uint renames Hi_Left;
      Rlo : Uint := Lo_Right;
      Rhi : Uint := Hi_Right;

   begin
      --  We will compute a range for the result in almost all cases

      OK := True;

      case Op is

         --  Absolute value

         when N_Op_Abs =>
            Lo := Uint_0;
            Hi := UI_Max (abs Rlo, abs Rhi);

         --  Addition

         when N_Op_Add =>
            Lo := Llo + Rlo;
            Hi := Lhi + Rhi;

         --  Division

         when N_Op_Divide =>

            --  If the right operand can only be zero, set 0..0

            if Rlo = 0 and then Rhi = 0 then
               Lo := Uint_0;
               Hi := Uint_0;

            --  Possible bounds of division must come from dividing end
            --  values of the input ranges (four possibilities), provided
            --  zero is not included in the possible values of the right
            --  operand.

            --  Otherwise, we just consider two intervals of values for
            --  the right operand: the interval of negative values (up to
            --  -1) and the interval of positive values (starting at 1).
            --  Since division by 1 is the identity, and division by -1
            --  is negation, we get all possible bounds of division in that
            --  case by considering:
            --    - all values from the division of end values of input
            --      ranges;
            --    - the end values of the left operand;
            --    - the negation of the end values of the left operand.

            else
               declare
                  Mrk : constant Uintp.Save_Mark := Mark;
                  --  Mark so we can release the RR and Ev values

                  Ev1 : Uint;
                  Ev2 : Uint;
                  Ev3 : Uint;
                  Ev4 : Uint;

               begin
                  --  Discard extreme values of zero for the divisor, since
                  --  they will simply result in an exception in any case.

                  if Rlo = 0 then
                     Rlo := Uint_1;
                  elsif Rhi = 0 then
                     Rhi := -Uint_1;
                  end if;

                  --  Compute possible bounds coming from dividing end
                  --  values of the input ranges.

                  Ev1 := Llo / Rlo;
                  Ev2 := Llo / Rhi;
                  Ev3 := Lhi / Rlo;
                  Ev4 := Lhi / Rhi;

                  Lo := UI_Min (UI_Min (Ev1, Ev2), UI_Min (Ev3, Ev4));
                  Hi := UI_Max (UI_Max (Ev1, Ev2), UI_Max (Ev3, Ev4));

                  --  If the right operand can be both negative or positive,
                  --  include the end values of the left operand in the
                  --  extreme values, as well as their negation.

                  if Rlo < 0 and then Rhi > 0 then
                     Ev1 := Llo;
                     Ev2 := -Llo;
                     Ev3 := Lhi;
                     Ev4 := -Lhi;

                     Lo := UI_Min (Lo,
                             UI_Min (UI_Min (Ev1, Ev2), UI_Min (Ev3, Ev4)));
                     Hi := UI_Max (Hi,
                             UI_Max (UI_Max (Ev1, Ev2), UI_Max (Ev3, Ev4)));
                  end if;

                  --  Release the RR and Ev values

                  Release_And_Save (Mrk, Lo, Hi);
               end;
            end if;

         --  Exponentiation

         when N_Op_Expon =>

            --  Discard negative values for the exponent, since they will
            --  simply result in an exception in any case.

            if Rhi < 0 then
               Rhi := Uint_0;
            elsif Rlo < 0 then
               Rlo := Uint_0;
            end if;

            --  Estimate number of bits in result before we go computing
            --  giant useless bounds. Basically the number of bits in the
            --  result is the number of bits in the base multiplied by the
            --  value of the exponent. If this is big enough that the result
            --  definitely won't fit in Long_Long_Integer, return immediately
            --  and avoid computing giant bounds.

            --  The comparison here is approximate, but conservative, it
            --  only clicks on cases that are sure to exceed the bounds.

            if Num_Bits (UI_Max (abs Llo, abs Lhi)) * Rhi + 1 > 100 then
               Lo := No_Uint;
               Hi := No_Uint;
               OK := False;
               return;

            --  If right operand is zero then result is 1

            elsif Rhi = 0 then
               Lo := Uint_1;
               Hi := Uint_1;

            else
               --  High bound comes either from exponentiation of largest
               --  positive value to largest exponent value, or from
               --  the exponentiation of most negative value to an
               --  even exponent.

               declare
                  Hi1, Hi2 : Uint;

               begin
                  if Lhi > 0 then
                     Hi1 := Lhi ** Rhi;
                  else
                     Hi1 := Uint_0;
                  end if;

                  if Llo < 0 then
                     if Rhi mod 2 = 0 then
                        Hi2 := Llo ** Rhi;
                     else
                        Hi2 := Llo ** (Rhi - 1);
                     end if;
                  else
                     Hi2 := Uint_0;
                  end if;

                  Hi := UI_Max (Hi1, Hi2);
               end;

               --  Result can only be negative if base can be negative

               if Llo < 0 then
                  if Rhi mod 2 = 0 then
                     Lo := Llo ** (Rhi - 1);
                  else
                     Lo := Llo ** Rhi;
                  end if;

               --  Otherwise low bound is minimum ** minimum

               else
                  Lo := Llo ** Rlo;
               end if;
            end if;

         --  Negation

         when N_Op_Minus =>
            Lo := -Rhi;
            Hi := -Rlo;

         --  Mod

         when N_Op_Mod =>
            declare
               Maxabs : constant Uint := UI_Max (abs Rlo, abs Rhi) - 1;
               --  This is the maximum absolute value of the result

            begin
               Lo := Uint_0;
               Hi := Uint_0;

               --  The result depends only on the sign and magnitude of
               --  the right operand, it does not depend on the sign or
               --  magnitude of the left operand.

               if Rlo < 0 then
                  Lo := -Maxabs;
               end if;

               if Rhi > 0 then
                  Hi := Maxabs;
               end if;
            end;

         --  Multiplication

         when N_Op_Multiply =>

            --  Possible bounds of multiplication must come from multiplying
            --  end values of the input ranges (four possibilities).

            declare
               Mrk : constant Uintp.Save_Mark := Mark;
               --  Mark so we can release the Ev values

               Ev1 : constant Uint := Llo * Rlo;
               Ev2 : constant Uint := Llo * Rhi;
               Ev3 : constant Uint := Lhi * Rlo;
               Ev4 : constant Uint := Lhi * Rhi;

            begin
               Lo := UI_Min (UI_Min (Ev1, Ev2), UI_Min (Ev3, Ev4));
               Hi := UI_Max (UI_Max (Ev1, Ev2), UI_Max (Ev3, Ev4));

               --  Release the Ev values

               Release_And_Save (Mrk, Lo, Hi);
            end;

         --  Plus operator (affirmation)

         when N_Op_Plus =>
            Lo := Rlo;
            Hi := Rhi;

         --  Remainder

         when N_Op_Rem =>
            declare
               Maxabs : constant Uint := UI_Max (abs Rlo, abs Rhi) - 1;
               --  This is the maximum absolute value of the result. Note
               --  that the result range does not depend on the sign of the
               --  right operand.

            begin
               Lo := Uint_0;
               Hi := Uint_0;

               --  Case of left operand negative, which results in a range
               --  of -Maxabs .. 0 for those negative values. If there are
               --  no negative values then Lo value of result is always 0.

               if Llo < 0 then
                  Lo := -Maxabs;
               end if;

               --  Case of left operand positive

               if Lhi > 0 then
                  Hi := Maxabs;
               end if;
            end;

         --  Subtract

         when N_Op_Subtract =>
            Lo := Llo - Rhi;
            Hi := Lhi - Rlo;

         --  Nothing else should be possible

         when others =>
            raise Program_Error;
      end case;
   end Compute_Range_For_Arithmetic_Op;

   ----------------------------------
   -- Conditional_Statements_Begin --
   ----------------------------------

   procedure Conditional_Statements_Begin is
   begin
      Saved_Checks_TOS := Saved_Checks_TOS + 1;

      --  If stack overflows, kill all checks, that way we know to simply reset
      --  the number of saved checks to zero on return. This should never occur
      --  in practice.

      if Saved_Checks_TOS > Saved_Checks_Stack'Last then
         Kill_All_Checks;

      --  In the normal case, we just make a new stack entry saving the current
      --  number of saved checks for a later restore.

      else
         Saved_Checks_Stack (Saved_Checks_TOS) := Num_Saved_Checks;

         if Debug_Flag_CC then
            w ("Conditional_Statements_Begin: Num_Saved_Checks = ",
               Num_Saved_Checks);
         end if;
      end if;
   end Conditional_Statements_Begin;

   --------------------------------
   -- Conditional_Statements_End --
   --------------------------------

   procedure Conditional_Statements_End is
   begin
      pragma Assert (Saved_Checks_TOS > 0);

      --  If the saved checks stack overflowed, then we killed all checks, so
      --  setting the number of saved checks back to zero is correct. This
      --  should never occur in practice.

      if Saved_Checks_TOS > Saved_Checks_Stack'Last then
         Num_Saved_Checks := 0;

      --  In the normal case, restore the number of saved checks from the top
      --  stack entry.

      else
         Num_Saved_Checks := Saved_Checks_Stack (Saved_Checks_TOS);

         if Debug_Flag_CC then
            w ("Conditional_Statements_End: Num_Saved_Checks = ",
               Num_Saved_Checks);
         end if;
      end if;

      Saved_Checks_TOS := Saved_Checks_TOS - 1;
   end Conditional_Statements_End;

   -------------------------
   -- Convert_From_Bignum --
   -------------------------

   function Convert_From_Bignum (N : Node_Id) return Node_Id is
      Loc : constant Source_Ptr := Sloc (N);

   begin
      pragma Assert (Is_RTE (Etype (N), RE_Bignum));

      --  Construct call From Bignum

      return
        Make_Function_Call (Loc,
          Name                   =>
            New_Occurrence_Of (RTE (RE_From_Bignum), Loc),
          Parameter_Associations => New_List (Relocate_Node (N)));
   end Convert_From_Bignum;

   -----------------------
   -- Convert_To_Bignum --
   -----------------------

   function Convert_To_Bignum (N : Node_Id) return Node_Id is
      Loc : constant Source_Ptr := Sloc (N);

   begin
      --  Nothing to do if Bignum already except call Relocate_Node

      if Is_RTE (Etype (N), RE_Bignum) then
         return Relocate_Node (N);

      --  Otherwise construct call to To_Bignum, converting the operand to the
      --  required Long_Long_Integer form.

      else
         pragma Assert (Is_Signed_Integer_Type (Etype (N)));
         return
           Make_Function_Call (Loc,
             Name                   =>
               New_Occurrence_Of (RTE (RE_To_Bignum), Loc),
             Parameter_Associations => New_List (
               Convert_To (Standard_Long_Long_Integer, Relocate_Node (N))));
      end if;
   end Convert_To_Bignum;

   ---------------------
   -- Determine_Range --
   ---------------------

   Cache_Size : constant := 2 ** 10;
   type Cache_Index is range 0 .. Cache_Size - 1;
   --  Determine size of below cache (power of 2 is more efficient)

   Determine_Range_Cache_N    : array (Cache_Index) of Node_Id;
   Determine_Range_Cache_O    : array (Cache_Index) of Node_Id;
   Determine_Range_Cache_V    : array (Cache_Index) of Boolean;
   Determine_Range_Cache_Lo   : array (Cache_Index) of Uint;
   Determine_Range_Cache_Hi   : array (Cache_Index) of Uint;
   Determine_Range_Cache_Lo_R : array (Cache_Index) of Ureal;
   Determine_Range_Cache_Hi_R : array (Cache_Index) of Ureal;
   --  The above arrays are used to implement a small direct cache for
   --  Determine_Range and Determine_Range_R calls. Because of the way these
   --  subprograms recursively traces subexpressions, and because overflow
   --  checking calls the routine on the way up the tree, a quadratic behavior
   --  can otherwise be encountered in large expressions. The cache entry for
   --  node N is stored in the (N mod Cache_Size) entry, and can be validated
   --  by checking the actual node value stored there. The Range_Cache_O array
   --  records the setting of Original_Node (N) so that the cache entry does
   --  not become stale when the node N is rewritten. The Range_Cache_V array
   --  records the setting of Assume_Valid for the cache entry.

   procedure Determine_Range
     (N            : Node_Id;
      OK           : out Boolean;
      Lo           : out Uint;
      Hi           : out Uint;
      Assume_Valid : Boolean := False)
   is
      Kind : constant Node_Kind := Nkind (N);
      --  Kind of node

      function Half_Address_Space return Uint;
      --  The size of half the total addressable memory space in storage units
      --  (minus one, so that the size fits in a signed integer whose size is
      --  System_Address_Size, which helps in various cases).

      ------------------------
      -- Half_Address_Space --
      ------------------------

      function Half_Address_Space return Uint is
      begin
         return Uint_2 ** (System_Address_Size - 1) - 1;
      end Half_Address_Space;

      --  Local variables

      Typ : Entity_Id := Etype (N);
      --  Type to use, may get reset to base type for possibly invalid entity

      Lo_Left : Uint := No_Uint;
      Hi_Left : Uint := No_Uint;
      --  Lo and Hi bounds of left operand

      Lo_Right : Uint := No_Uint;
      Hi_Right : Uint := No_Uint;
      --  Lo and Hi bounds of right (or only) operand

      Bound : Node_Id;
      --  Temp variable used to hold a bound node

      Hbound : Uint;
      --  High bound of base type of expression

      Lor : Uint;
      Hir : Uint;
      --  Refined values for low and high bounds, after tightening

      OK1 : Boolean;
      --  Used in lower level calls to indicate if call succeeded

      Cindex : Cache_Index;
      --  Used to search cache

      Btyp : Entity_Id;
      --  Base type

   --  Start of processing for Determine_Range

   begin
      --  Prevent junk warnings by initializing range variables

      Lo  := No_Uint;
      Hi  := No_Uint;
      Lor := No_Uint;
      Hir := No_Uint;

      --  For temporary constants internally generated to remove side effects
      --  we must use the corresponding expression to determine the range of
      --  the expression. But note that the expander can also generate
      --  constants in other cases, including deferred constants.

      if Is_Entity_Name (N)
        and then Nkind (Parent (Entity (N))) = N_Object_Declaration
        and then Ekind (Entity (N)) = E_Constant
        and then Is_Internal_Name (Chars (Entity (N)))
      then
         if Present (Expression (Parent (Entity (N)))) then
            Determine_Range
              (Expression (Parent (Entity (N))), OK, Lo, Hi, Assume_Valid);

         elsif Present (Full_View (Entity (N))) then
            Determine_Range
              (Expression (Parent (Full_View (Entity (N)))),
               OK, Lo, Hi, Assume_Valid);

         else
            OK := False;
         end if;
         return;
      end if;

      --  If type is not defined, we can't determine its range

      if No (Typ)

        --  We don't deal with anything except discrete types

        or else not Is_Discrete_Type (Typ)

        --  Don't deal with enumerated types with non-standard representation

        or else (Is_Enumeration_Type (Typ)
                   and then Present (Enum_Pos_To_Rep (Base_Type (Typ))))

        --  Ignore type for which an error has been posted, since range in
        --  this case may well be a bogosity deriving from the error. Also
        --  ignore if error posted on the reference node.

        or else Error_Posted (N) or else Error_Posted (Typ)
      then
         OK := False;
         return;
      end if;

      --  For all other cases, we can determine the range

      OK := True;

      --  If value is compile time known, then the possible range is the one
      --  value that we know this expression definitely has.

      if Compile_Time_Known_Value (N) then
         Lo := Expr_Value (N);
         Hi := Lo;
         return;
      end if;

      --  Return if already in the cache

      Cindex := Cache_Index (N mod Cache_Size);

      if Determine_Range_Cache_N (Cindex) = N
           and then
         Determine_Range_Cache_O (Cindex) = Original_Node (N)
           and then
         Determine_Range_Cache_V (Cindex) = Assume_Valid
      then
         Lo := Determine_Range_Cache_Lo (Cindex);
         Hi := Determine_Range_Cache_Hi (Cindex);
         return;
      end if;

      --  Otherwise, start by finding the bounds of the type of the expression,
      --  the value cannot be outside this range (if it is, then we have an
      --  overflow situation, which is a separate check, we are talking here
      --  only about the expression value).

      --  First a check, never try to find the bounds of a generic type, since
      --  these bounds are always junk values, and it is only valid to look at
      --  the bounds in an instance.

      if Is_Generic_Type (Typ) then
         OK := False;
         return;
      end if;

      --  First step, change to use base type unless we know the value is valid

      if (Is_Entity_Name (N) and then Is_Known_Valid (Entity (N)))
        or else Assume_No_Invalid_Values
        or else Assume_Valid
      then
         --  If this is a known valid constant with a nonstatic value, it may
         --  have inherited a narrower subtype from its initial value; use this
         --  saved subtype (see sem_ch3.adb).

         if Is_Entity_Name (N)
           and then Ekind (Entity (N)) = E_Constant
           and then Present (Actual_Subtype (Entity (N)))
         then
            Typ := Actual_Subtype (Entity (N));
         end if;

      else
         Typ := Underlying_Type (Base_Type (Typ));
      end if;

      --  Retrieve the base type. Handle the case where the base type is a
      --  private enumeration type.

      Btyp := Base_Type (Typ);

      if Is_Private_Type (Btyp) and then Present (Full_View (Btyp)) then
         Btyp := Full_View (Btyp);
      end if;

      --  We use the actual bound unless it is dynamic, in which case use the
      --  corresponding base type bound if possible. If we can't get a bound
      --  then we figure we can't determine the range (a peculiar case, that
      --  perhaps cannot happen, but there is no point in bombing in this
      --  optimization circuit).

      --  First the low bound

      Bound := Type_Low_Bound (Typ);

      if Compile_Time_Known_Value (Bound) then
         Lo := Expr_Value (Bound);

      elsif Compile_Time_Known_Value (Type_Low_Bound (Btyp)) then
         Lo := Expr_Value (Type_Low_Bound (Btyp));

      else
         OK := False;
         return;
      end if;

      --  Now the high bound

      Bound := Type_High_Bound (Typ);

      --  We need the high bound of the base type later on, and this should
      --  always be compile time known. Again, it is not clear that this
      --  can ever be false, but no point in bombing.

      if Compile_Time_Known_Value (Type_High_Bound (Btyp)) then
         Hbound := Expr_Value (Type_High_Bound (Btyp));
         Hi := Hbound;

      else
         OK := False;
         return;
      end if;

      --  If we have a static subtype, then that may have a tighter bound so
      --  use the upper bound of the subtype instead in this case.

      if Compile_Time_Known_Value (Bound) then
         Hi := Expr_Value (Bound);
      end if;

      --  We may be able to refine this value in certain situations. If any
      --  refinement is possible, then Lor and Hir are set to possibly tighter
      --  bounds, and OK1 is set to True.

      case Kind is

         --  Unary operation case

         when N_Op_Abs
            | N_Op_Minus
            | N_Op_Plus
         =>
            Determine_Range
              (Right_Opnd (N), OK1, Lo_Right, Hi_Right, Assume_Valid);

            if OK1 then
               Compute_Range_For_Arithmetic_Op
                 (Kind, Lo_Left, Hi_Left, Lo_Right, Hi_Right, OK1, Lor, Hir);
            end if;

         --  Binary operation case

         when N_Op_Add
            | N_Op_Divide
            | N_Op_Expon
            | N_Op_Mod
            | N_Op_Multiply
            | N_Op_Rem
            | N_Op_Subtract
         =>
            Determine_Range
              (Left_Opnd (N), OK1, Lo_Left, Hi_Left, Assume_Valid);

            if OK1 then
               Determine_Range
                 (Right_Opnd (N), OK1, Lo_Right, Hi_Right, Assume_Valid);
            end if;

            if OK1 then
               Compute_Range_For_Arithmetic_Op
                 (Kind, Lo_Left, Hi_Left, Lo_Right, Hi_Right, OK1, Lor, Hir);
            end if;

         --  Attribute reference cases

         when N_Attribute_Reference =>
            case Get_Attribute_Id (Attribute_Name (N)) is

               --  For Min/Max attributes, we can refine the range using the
               --  possible range of values of the attribute expressions.

               when Attribute_Min
                  | Attribute_Max
               =>
                  Determine_Range
                    (First (Expressions (N)),
                     OK1, Lo_Left, Hi_Left, Assume_Valid);

                  if OK1 then
                     Determine_Range
                       (Next (First (Expressions (N))),
                        OK1, Lo_Right, Hi_Right, Assume_Valid);
                  end if;

                  if OK1 then
                     Lor := UI_Min (Lo_Left, Lo_Right);
                     Hir := UI_Max (Hi_Left, Hi_Right);
                  end if;

               --  For Pos/Val attributes, we can refine the range using the
               --  possible range of values of the attribute expression.

               when Attribute_Pos
                  | Attribute_Val
               =>
                  Determine_Range
                    (First (Expressions (N)), OK1, Lor, Hir, Assume_Valid);

               --  For Length and Range_Length attributes, use the bounds of
               --  the (corresponding index) type to refine the range.

               when Attribute_Length
                  | Attribute_Range_Length
               =>
                  declare
                     Ptyp : Entity_Id;
                     Ityp : Entity_Id;

                     LL, LU : Uint;
                     UL, UU : Uint;

                  begin
                     Ptyp := Etype (Prefix (N));
                     if Is_Access_Type (Ptyp) then
                        Ptyp := Designated_Type (Ptyp);
                     end if;

                     --  For string literal, we know exact value

                     if Ekind (Ptyp) = E_String_Literal_Subtype then
                        OK := True;
                        Lo := String_Literal_Length (Ptyp);
                        Hi := String_Literal_Length (Ptyp);
                        return;
                     end if;

                     if Is_Array_Type (Ptyp) then
                        Ityp := Get_Index_Subtype (N);
                     else
                        Ityp := Ptyp;
                     end if;

                     --  If the (index) type is a formal type or derived from
                     --  one, the bounds are not static.

                     if Is_Generic_Type (Root_Type (Ityp)) then
                        OK := False;
                        return;
                     end if;

                     Determine_Range
                       (Type_Low_Bound (Ityp), OK1, LL, LU, Assume_Valid);

                     if OK1 then
                        Determine_Range
                          (Type_High_Bound (Ityp), OK1, UL, UU, Assume_Valid);

                        if OK1 then
                           --  The maximum value for Length is the biggest
                           --  possible gap between the values of the bounds.
                           --  But of course, this value cannot be negative.

                           Hir := UI_Max (Uint_0, UU - LL + 1);

                           --  For a constrained array, the minimum value for
                           --  Length is taken from the actual value of the
                           --  bounds, since the index will be exactly of this
                           --  subtype.

                           if Is_Constrained (Ptyp) then
                              Lor := UI_Max (Uint_0, UL - LU + 1);

                           --  For an unconstrained array, the minimum value
                           --  for length is always zero.

                           else
                              Lor := Uint_0;
                           end if;
                        end if;
                     end if;

                     --  Small optimization: the maximum size in storage units
                     --  an object can have with GNAT is half of the address
                     --  space, so we can bound the length of an array declared
                     --  in Interfaces (or its children) because its component
                     --  size is at least the storage unit and it is meant to
                     --  be used to interface actual array objects.

                     if Is_Array_Type (Ptyp) then
                        declare
                           S : constant Entity_Id := Scope (Base_Type (Ptyp));
                        begin
                           if Is_RTU (S, Interfaces)
                             or else (S /= Standard_Standard
                                       and then Is_RTU (Scope (S), Interfaces))
                           then
                              Hir := UI_Min (Hir, Half_Address_Space);
                           end if;
                        end;
                     end if;
                  end;

               --  The maximum default alignment is quite low, but GNAT accepts
               --  alignment clauses that are fairly large, but not as large as
               --  the maximum size of objects, see below.

               when Attribute_Alignment =>
                  Lor := Uint_0;
                  Hir := Half_Address_Space;
                  OK1 := True;

               --  The attribute should have been folded if a component clause
               --  was specified, so we assume there is none.

               when Attribute_Bit
                  | Attribute_First_Bit
               =>
                  Lor := Uint_0;
                  Hir := UI_From_Int (System_Storage_Unit - 1);
                  OK1 := True;

               --  Likewise about the component clause. Note that Last_Bit
               --  yields -1 for a field of size 0 if First_Bit is 0.

               when Attribute_Last_Bit =>
                  Lor := Uint_Minus_1;
                  Hir := Hi;
                  OK1 := True;

               --  Likewise about the component clause for Position. The
               --  maximum size in storage units that an object can have
               --  with GNAT is half of the address space.

               when Attribute_Max_Size_In_Storage_Elements
                  | Attribute_Position
               =>
                  Lor := Uint_0;
                  Hir := Half_Address_Space;
                  OK1 := True;

               --  These attributes yield a nonnegative value (we do not set
               --  the maximum value because it is too large to be useful).

               when Attribute_Bit_Position
                  | Attribute_Component_Size
                  | Attribute_Object_Size
                  | Attribute_Size
                  | Attribute_Value_Size
               =>
                  Lor := Uint_0;
                  Hir := Hi;
                  OK1 := True;

               --  The maximum size is the sum of twice the size of the largest
               --  integer for every dimension, rounded up to the next multiple
               --  of the maximum alignment, but we add instead of rounding.

               when Attribute_Descriptor_Size =>
                  declare
                     Max_Align : constant Pos :=
                                   Maximum_Alignment * System_Storage_Unit;
                     Max_Size  : constant Uint :=
                                   2 * Esize (Universal_Integer);
                     Ndims     : constant Pos :=
                                   Number_Dimensions (Etype (Prefix (N)));
                  begin
                     Lor := Uint_0;
                     Hir := Max_Size * Ndims + Max_Align;
                     OK1 := True;
                  end;

               --  No special handling for other attributes for now

               when others =>
                  OK1 := False;

            end case;

         when N_Type_Conversion =>
            --  For a type conversion, we can try to refine the range using the
            --  converted value.

            Determine_Range_To_Discrete
              (Expression (N), OK1, Lor, Hir, Conversion_OK (N), Assume_Valid);

         --  Nothing special to do for all other expression kinds

         when others =>
            OK1 := False;
            Lor := No_Uint;
            Hir := No_Uint;
      end case;

      --  At this stage, if OK1 is true, then we know that the actual result of
      --  the computed expression is in the range Lor .. Hir. We can use this
      --  to restrict the possible range of results.

      if OK1 then

         --  If the refined value of the low bound is greater than the type
         --  low bound, then reset it to the more restrictive value. However,
         --  we do NOT do this for the case of a modular type where the
         --  possible upper bound on the value is above the base type high
         --  bound, because that means the result could wrap.

         if Lor > Lo
           and then not (Is_Modular_Integer_Type (Typ) and then Hir > Hbound)
         then
            Lo := Lor;
         end if;

         --  Similarly, if the refined value of the high bound is less than the
         --  value so far, then reset it to the more restrictive value. Again,
         --  we do not do this if the refined low bound is negative for a
         --  modular type, since this would wrap.

         if Hir < Hi
           and then not (Is_Modular_Integer_Type (Typ) and then Lor < Uint_0)
         then
            Hi := Hir;
         end if;
      end if;

      --  Set cache entry for future call and we are all done

      Determine_Range_Cache_N  (Cindex) := N;
      Determine_Range_Cache_O  (Cindex) := Original_Node (N);
      Determine_Range_Cache_V  (Cindex) := Assume_Valid;
      Determine_Range_Cache_Lo (Cindex) := Lo;
      Determine_Range_Cache_Hi (Cindex) := Hi;
      return;

   --  If any exception occurs, it means that we have some bug in the compiler,
   --  possibly triggered by a previous error, or by some unforeseen peculiar
   --  occurrence. However, this is only an optimization attempt, so there is
   --  really no point in crashing the compiler. Instead we just decide, too
   --  bad, we can't figure out a range in this case after all.

   exception
      when others =>

         --  Debug flag K disables this behavior (useful for debugging)

         if Debug_Flag_K then
            raise;
         else
            OK := False;
            Lo := No_Uint;
            Hi := No_Uint;
            return;
         end if;
   end Determine_Range;

   -----------------------
   -- Determine_Range_R --
   -----------------------

   procedure Determine_Range_R
     (N            : Node_Id;
      OK           : out Boolean;
      Lo           : out Ureal;
      Hi           : out Ureal;
      Assume_Valid : Boolean := False)
   is
      Typ : Entity_Id := Etype (N);
      --  Type to use, may get reset to base type for possibly invalid entity

      Lo_Left : Ureal;
      Hi_Left : Ureal;
      --  Lo and Hi bounds of left operand

      Lo_Right : Ureal := No_Ureal;
      Hi_Right : Ureal := No_Ureal;
      --  Lo and Hi bounds of right (or only) operand

      Bound : Node_Id;
      --  Temp variable used to hold a bound node

      Hbound : Ureal;
      --  High bound of base type of expression

      Lor : Ureal;
      Hir : Ureal;
      --  Refined values for low and high bounds, after tightening

      OK1 : Boolean;
      --  Used in lower level calls to indicate if call succeeded

      Cindex : Cache_Index;
      --  Used to search cache

      Btyp : Entity_Id;
      --  Base type

      function OK_Operands return Boolean;
      --  Used for binary operators. Determines the ranges of the left and
      --  right operands, and if they are both OK, returns True, and puts
      --  the results in Lo_Right, Hi_Right, Lo_Left, Hi_Left.

      function Round_Machine (B : Ureal) return Ureal;
      --  B is a real bound. Round it using mode Round_Even.

      -----------------
      -- OK_Operands --
      -----------------

      function OK_Operands return Boolean is
      begin
         Determine_Range_R
           (Left_Opnd  (N), OK1, Lo_Left,  Hi_Left, Assume_Valid);

         if not OK1 then
            return False;
         end if;

         Determine_Range_R
           (Right_Opnd (N), OK1, Lo_Right, Hi_Right, Assume_Valid);
         return OK1;
      end OK_Operands;

      -------------------
      -- Round_Machine --
      -------------------

      function Round_Machine (B : Ureal) return Ureal is
      begin
         return Machine (Typ, B, Round_Even, N);
      end Round_Machine;

   --  Start of processing for Determine_Range_R

   begin
      --  Prevent junk warnings by initializing range variables

      Lo  := No_Ureal;
      Hi  := No_Ureal;
      Lor := No_Ureal;
      Hir := No_Ureal;

      --  For temporary constants internally generated to remove side effects
      --  we must use the corresponding expression to determine the range of
      --  the expression. But note that the expander can also generate
      --  constants in other cases, including deferred constants.

      if Is_Entity_Name (N)
        and then Nkind (Parent (Entity (N))) = N_Object_Declaration
        and then Ekind (Entity (N)) = E_Constant
        and then Is_Internal_Name (Chars (Entity (N)))
      then
         if Present (Expression (Parent (Entity (N)))) then
            Determine_Range_R
              (Expression (Parent (Entity (N))), OK, Lo, Hi, Assume_Valid);

         elsif Present (Full_View (Entity (N))) then
            Determine_Range_R
              (Expression (Parent (Full_View (Entity (N)))),
               OK, Lo, Hi, Assume_Valid);

         else
            OK := False;
         end if;

         return;
      end if;

      --  If type is not defined, we can't determine its range

      pragma Warnings (Off, "condition can only be True if invalid");
      --  Otherwise the compiler warns on the check of Float_Rep below, because
      --  there is only one value (see types.ads).

      if No (Typ)

        --  We don't deal with anything except IEEE floating-point types

        or else not Is_Floating_Point_Type (Typ)
        or else Float_Rep (Typ) /= IEEE_Binary

        --  Ignore type for which an error has been posted, since range in
        --  this case may well be a bogosity deriving from the error. Also
        --  ignore if error posted on the reference node.

        or else Error_Posted (N) or else Error_Posted (Typ)
      then
         pragma Warnings (On, "condition can only be True if invalid");
         OK := False;
         return;
      end if;

      --  For all other cases, we can determine the range

      OK := True;

      --  If value is compile time known, then the possible range is the one
      --  value that we know this expression definitely has.

      if Compile_Time_Known_Value (N) then
         Lo := Expr_Value_R (N);
         Hi := Lo;
         return;
      end if;

      --  Return if already in the cache

      Cindex := Cache_Index (N mod Cache_Size);

      if Determine_Range_Cache_N (Cindex) = N
           and then
         Determine_Range_Cache_O (Cindex) = Original_Node (N)
           and then
         Determine_Range_Cache_V (Cindex) = Assume_Valid
      then
         Lo := Determine_Range_Cache_Lo_R (Cindex);
         Hi := Determine_Range_Cache_Hi_R (Cindex);
         return;
      end if;

      --  Otherwise, start by finding the bounds of the type of the expression,
      --  the value cannot be outside this range (if it is, then we have an
      --  overflow situation, which is a separate check, we are talking here
      --  only about the expression value).

      --  First a check, never try to find the bounds of a generic type, since
      --  these bounds are always junk values, and it is only valid to look at
      --  the bounds in an instance.

      if Is_Generic_Type (Typ) then
         OK := False;
         return;
      end if;

      --  First step, change to use base type unless we know the value is valid

      if (Is_Entity_Name (N) and then Is_Known_Valid (Entity (N)))
        or else Assume_No_Invalid_Values
        or else Assume_Valid
      then
         null;
      else
         Typ := Underlying_Type (Base_Type (Typ));
      end if;

      --  Retrieve the base type. Handle the case where the base type is a
      --  private type.

      Btyp := Base_Type (Typ);

      if Is_Private_Type (Btyp) and then Present (Full_View (Btyp)) then
         Btyp := Full_View (Btyp);
      end if;

      --  We use the actual bound unless it is dynamic, in which case use the
      --  corresponding base type bound if possible. If we can't get a bound
      --  then we figure we can't determine the range (a peculiar case, that
      --  perhaps cannot happen, but there is no point in bombing in this
      --  optimization circuit).

      --  First the low bound

      Bound := Type_Low_Bound (Typ);

      if Compile_Time_Known_Value (Bound) then
         Lo := Expr_Value_R (Bound);

      elsif Compile_Time_Known_Value (Type_Low_Bound (Btyp)) then
         Lo := Expr_Value_R (Type_Low_Bound (Btyp));

      else
         OK := False;
         return;
      end if;

      --  Now the high bound

      Bound := Type_High_Bound (Typ);

      --  We need the high bound of the base type later on, and this should
      --  always be compile time known. Again, it is not clear that this
      --  can ever be false, but no point in bombing.

      if Compile_Time_Known_Value (Type_High_Bound (Btyp)) then
         Hbound := Expr_Value_R (Type_High_Bound (Btyp));
         Hi := Hbound;

      else
         OK := False;
         return;
      end if;

      --  If we have a static subtype, then that may have a tighter bound so
      --  use the upper bound of the subtype instead in this case.

      if Compile_Time_Known_Value (Bound) then
         Hi := Expr_Value_R (Bound);
      end if;

      --  We may be able to refine this value in certain situations. If any
      --  refinement is possible, then Lor and Hir are set to possibly tighter
      --  bounds, and OK1 is set to True.

      case Nkind (N) is

         --  For unary plus, result is limited by range of operand

         when N_Op_Plus =>
            Determine_Range_R
              (Right_Opnd (N), OK1, Lor, Hir, Assume_Valid);

         --  For unary minus, determine range of operand, and negate it

         when N_Op_Minus =>
            Determine_Range_R
              (Right_Opnd (N), OK1, Lo_Right, Hi_Right, Assume_Valid);

            if OK1 then
               Lor := -Hi_Right;
               Hir := -Lo_Right;
            end if;

         --  For binary addition, get range of each operand and do the
         --  addition to get the result range.

         when N_Op_Add =>
            if OK_Operands then
               Lor := Round_Machine (Lo_Left + Lo_Right);
               Hir := Round_Machine (Hi_Left + Hi_Right);
            end if;

         --  For binary subtraction, get range of each operand and do the worst
         --  case subtraction to get the result range.

         when N_Op_Subtract =>
            if OK_Operands then
               Lor := Round_Machine (Lo_Left - Hi_Right);
               Hir := Round_Machine (Hi_Left - Lo_Right);
            end if;

         --  For multiplication, get range of each operand and do the
         --  four multiplications to get the result range.

         when N_Op_Multiply =>
            if OK_Operands then
               declare
                  M1 : constant Ureal := Round_Machine (Lo_Left * Lo_Right);
                  M2 : constant Ureal := Round_Machine (Lo_Left * Hi_Right);
                  M3 : constant Ureal := Round_Machine (Hi_Left * Lo_Right);
                  M4 : constant Ureal := Round_Machine (Hi_Left * Hi_Right);

               begin
                  Lor := UR_Min (UR_Min (M1, M2), UR_Min (M3, M4));
                  Hir := UR_Max (UR_Max (M1, M2), UR_Max (M3, M4));
               end;
            end if;

         --  For division, consider separately the cases where the right
         --  operand is positive or negative. Otherwise, the right operand
         --  can be arbitrarily close to zero, so the result is likely to
         --  be unbounded in one direction, do not attempt to compute it.

         when N_Op_Divide =>
            if OK_Operands then

               --  Right operand is positive

               if Lo_Right > Ureal_0 then

                  --  If the low bound of the left operand is negative, obtain
                  --  the overall low bound by dividing it by the smallest
                  --  value of the right operand, and otherwise by the largest
                  --  value of the right operand.

                  if Lo_Left < Ureal_0 then
                     Lor := Round_Machine (Lo_Left / Lo_Right);
                  else
                     Lor := Round_Machine (Lo_Left / Hi_Right);
                  end if;

                  --  If the high bound of the left operand is negative, obtain
                  --  the overall high bound by dividing it by the largest
                  --  value of the right operand, and otherwise by the
                  --  smallest value of the right operand.

                  if Hi_Left < Ureal_0 then
                     Hir := Round_Machine (Hi_Left / Hi_Right);
                  else
                     Hir := Round_Machine (Hi_Left / Lo_Right);
                  end if;

               --  Right operand is negative

               elsif Hi_Right < Ureal_0 then

                  --  If the low bound of the left operand is negative, obtain
                  --  the overall low bound by dividing it by the largest
                  --  value of the right operand, and otherwise by the smallest
                  --  value of the right operand.

                  if Lo_Left < Ureal_0 then
                     Lor := Round_Machine (Lo_Left / Hi_Right);
                  else
                     Lor := Round_Machine (Lo_Left / Lo_Right);
                  end if;

                  --  If the high bound of the left operand is negative, obtain
                  --  the overall high bound by dividing it by the smallest
                  --  value of the right operand, and otherwise by the
                  --  largest value of the right operand.

                  if Hi_Left < Ureal_0 then
                     Hir := Round_Machine (Hi_Left / Lo_Right);
                  else
                     Hir := Round_Machine (Hi_Left / Hi_Right);
                  end if;

               else
                  OK1 := False;
               end if;
            end if;

         when N_Type_Conversion =>

            --  For type conversion from one floating-point type to another, we
            --  can refine the range using the converted value.

            if Is_Floating_Point_Type (Etype (Expression (N))) then
               Determine_Range_R (Expression (N), OK1, Lor, Hir, Assume_Valid);

            --  When converting an integer to a floating-point type, determine
            --  the range in integer first, and then convert the bounds.

            elsif Is_Discrete_Type (Etype (Expression (N))) then
               declare
                  Hir_Int : Uint;
                  Lor_Int : Uint;

               begin
                  Determine_Range
                    (Expression (N), OK1, Lor_Int, Hir_Int, Assume_Valid);

                  if OK1 then
                     Lor := Round_Machine (UR_From_Uint (Lor_Int));
                     Hir := Round_Machine (UR_From_Uint (Hir_Int));
                  end if;
               end;

            else
               OK1 := False;
            end if;

         --  Nothing special to do for all other expression kinds

         when others =>
            OK1 := False;
            Lor := No_Ureal;
            Hir := No_Ureal;
      end case;

      --  At this stage, if OK1 is true, then we know that the actual result of
      --  the computed expression is in the range Lor .. Hir. We can use this
      --  to restrict the possible range of results.

      if OK1 then

         --  If the refined value of the low bound is greater than the type
         --  low bound, then reset it to the more restrictive value.

         if Lor > Lo then
            Lo := Lor;
         end if;

         --  Similarly, if the refined value of the high bound is less than the
         --  value so far, then reset it to the more restrictive value.

         if Hir < Hi then
            Hi := Hir;
         end if;
      end if;

      --  Set cache entry for future call and we are all done

      Determine_Range_Cache_N    (Cindex) := N;
      Determine_Range_Cache_O    (Cindex) := Original_Node (N);
      Determine_Range_Cache_V    (Cindex) := Assume_Valid;
      Determine_Range_Cache_Lo_R (Cindex) := Lo;
      Determine_Range_Cache_Hi_R (Cindex) := Hi;
      return;

   --  If any exception occurs, it means that we have some bug in the compiler,
   --  possibly triggered by a previous error, or by some unforeseen peculiar
   --  occurrence. However, this is only an optimization attempt, so there is
   --  really no point in crashing the compiler. Instead we just decide, too
   --  bad, we can't figure out a range in this case after all.

   exception
      when others =>

         --  Debug flag K disables this behavior (useful for debugging)

         if Debug_Flag_K then
            raise;
         else
            OK := False;
            Lo := No_Ureal;
            Hi := No_Ureal;
            return;
         end if;
   end Determine_Range_R;

   ---------------------------------
   -- Determine_Range_To_Discrete --
   ---------------------------------

   procedure Determine_Range_To_Discrete
     (N            : Node_Id;
      OK           : out Boolean;
      Lo           : out Uint;
      Hi           : out Uint;
      Fixed_Int    : Boolean := False;
      Assume_Valid : Boolean := False)
   is
      Typ : constant Entity_Id := Etype (N);

   begin
      --  For a discrete type, simply defer to Determine_Range

      if Is_Discrete_Type (Typ) then
         Determine_Range (N, OK, Lo, Hi, Assume_Valid);

      --  For a fixed point type treated as an integer, we can determine the
      --  range using the Corresponding_Integer_Value of the bounds of the
      --  type or base type. This is done by the calls to Expr_Value below.

      elsif Is_Fixed_Point_Type (Typ) and then Fixed_Int then
         declare
            Btyp, Ftyp : Entity_Id;
            Bound      : Node_Id;

         begin
            if Assume_Valid then
               Ftyp := Typ;
            else
               Ftyp := Underlying_Type (Base_Type (Typ));
            end if;

            Btyp := Base_Type (Ftyp);

            --  First the low bound

            Bound := Type_Low_Bound (Ftyp);

            if Compile_Time_Known_Value (Bound) then
               Lo := Expr_Value (Bound);
            else
               Lo := Expr_Value (Type_Low_Bound (Btyp));
            end if;

            --  Then the high bound

            Bound := Type_High_Bound (Ftyp);

            if Compile_Time_Known_Value (Bound) then
               Hi := Expr_Value (Bound);
            else
               Hi := Expr_Value (Type_High_Bound (Btyp));
            end if;

            OK := True;
         end;

      --  For a floating-point type, we can determine the range in real first,
      --  and then convert the bounds using UR_To_Uint, which correctly rounds
      --  away from zero when half way between two integers, as required by
      --  normal Ada 95 rounding semantics. But this is only possible because
      --  GNATprove's analysis rules out the possibility of a NaN or infinite.

      elsif GNATprove_Mode and then Is_Floating_Point_Type (Typ) then
         declare
            Lo_Real, Hi_Real : Ureal;

         begin
            Determine_Range_R (N, OK, Lo_Real, Hi_Real, Assume_Valid);

            if OK then
               Lo := UR_To_Uint (Lo_Real);
               Hi := UR_To_Uint (Hi_Real);
            else
               Lo := No_Uint;
               Hi := No_Uint;
            end if;
         end;

      else
         Lo := No_Uint;
         Hi := No_Uint;
         OK := False;
      end if;
   end Determine_Range_To_Discrete;

   ------------------------------------
   -- Discriminant_Checks_Suppressed --
   ------------------------------------

   function Discriminant_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E) then
         if Is_Unchecked_Union (E) then
            return True;
         elsif Checks_May_Be_Suppressed (E) then
            return Is_Check_Suppressed (E, Discriminant_Check);
         end if;
      end if;

      return Scope_Suppress.Suppress (Discriminant_Check);
   end Discriminant_Checks_Suppressed;

   --------------------------------
   -- Division_Checks_Suppressed --
   --------------------------------

   function Division_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E) and then Checks_May_Be_Suppressed (E) then
         return Is_Check_Suppressed (E, Division_Check);
      else
         return Scope_Suppress.Suppress (Division_Check);
      end if;
   end Division_Checks_Suppressed;

   --------------------------------------
   -- Duplicated_Tag_Checks_Suppressed --
   --------------------------------------

   function Duplicated_Tag_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E) and then Checks_May_Be_Suppressed (E) then
         return Is_Check_Suppressed (E, Duplicated_Tag_Check);
      else
         return Scope_Suppress.Suppress (Duplicated_Tag_Check);
      end if;
   end Duplicated_Tag_Checks_Suppressed;

   -----------------------------------
   -- Elaboration_Checks_Suppressed --
   -----------------------------------

   function Elaboration_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      --  The complication in this routine is that if we are in the dynamic
      --  model of elaboration, we also check All_Checks, since All_Checks
      --  does not set Elaboration_Check explicitly.

      if Present (E) then
         if Kill_Elaboration_Checks (E) then
            return True;

         elsif Checks_May_Be_Suppressed (E) then
            if Is_Check_Suppressed (E, Elaboration_Check) then
               return True;

            elsif Dynamic_Elaboration_Checks then
               return Is_Check_Suppressed (E, All_Checks);

            else
               return False;
            end if;
         end if;
      end if;

      if Scope_Suppress.Suppress (Elaboration_Check) then
         return True;

      elsif Dynamic_Elaboration_Checks then
         return Scope_Suppress.Suppress (All_Checks);

      else
         return False;
      end if;
   end Elaboration_Checks_Suppressed;

   ---------------------------
   -- Enable_Overflow_Check --
   ---------------------------

   procedure Enable_Overflow_Check (N : Node_Id) is
      Typ  : constant Entity_Id          := Base_Type (Etype (N));
      Mode : constant Overflow_Mode_Type := Overflow_Check_Mode;
      Chk  : Nat;
      OK   : Boolean;
      Ent  : Entity_Id;
      Ofs  : Uint;
      Lo   : Uint;
      Hi   : Uint;

      Do_Ovflow_Check : Boolean;

   begin
      if Debug_Flag_CC then
         w ("Enable_Overflow_Check for node ", Int (N));
         Write_Str ("  Source location = ");
         wl (Sloc (N));
         pg (Union_Id (N));
      end if;

      --  No check if overflow checks suppressed for type of node

      if Overflow_Checks_Suppressed (Etype (N)) then
         return;

      --  Nothing to do for unsigned integer types, which do not overflow

      elsif Is_Modular_Integer_Type (Typ) then
         return;
      end if;

      --  This is the point at which processing for STRICT mode diverges
      --  from processing for MINIMIZED/ELIMINATED modes. This divergence is
      --  probably more extreme that it needs to be, but what is going on here
      --  is that when we introduced MINIMIZED/ELIMINATED modes, we wanted
      --  to leave the processing for STRICT mode untouched. There were
      --  two reasons for this. First it avoided any incompatible change of
      --  behavior. Second, it guaranteed that STRICT mode continued to be
      --  legacy reliable.

      --  The big difference is that in STRICT mode there is a fair amount of
      --  circuitry to try to avoid setting the Do_Overflow_Check flag if we
      --  know that no check is needed. We skip all that in the two new modes,
      --  since really overflow checking happens over a whole subtree, and we
      --  do the corresponding optimizations later on when applying the checks.

      if Mode in Minimized_Or_Eliminated then
         if not (Overflow_Checks_Suppressed (Etype (N)))
           and then not (Is_Entity_Name (N)
                          and then Overflow_Checks_Suppressed (Entity (N)))
         then
            Activate_Overflow_Check (N);
         end if;

         if Debug_Flag_CC then
            w ("Minimized/Eliminated mode");
         end if;

         return;
      end if;

      --  Remainder of processing is for STRICT case, and is unchanged from
      --  earlier versions preceding the addition of MINIMIZED/ELIMINATED.

      --  Nothing to do if the range of the result is known OK. We skip this
      --  for conversions, since the caller already did the check, and in any
      --  case the condition for deleting the check for a type conversion is
      --  different.

      if Nkind (N) /= N_Type_Conversion then
         Determine_Range (N, OK, Lo, Hi, Assume_Valid => True);

         --  Note in the test below that we assume that the range is not OK
         --  if a bound of the range is equal to that of the type. That's not
         --  quite accurate but we do this for the following reasons:

         --   a) The way that Determine_Range works, it will typically report
         --      the bounds of the value as being equal to the bounds of the
         --      type, because it either can't tell anything more precise, or
         --      does not think it is worth the effort to be more precise.

         --   b) It is very unusual to have a situation in which this would
         --      generate an unnecessary overflow check (an example would be
         --      a subtype with a range 0 .. Integer'Last - 1 to which the
         --      literal value one is added).

         --   c) The alternative is a lot of special casing in this routine
         --      which would partially duplicate Determine_Range processing.

         if OK then
            Do_Ovflow_Check := True;

            --  Note that the following checks are quite deliberately > and <
            --  rather than >= and <= as explained above.

            if  Lo > Expr_Value (Type_Low_Bound  (Typ))
                  and then
                Hi < Expr_Value (Type_High_Bound (Typ))
            then
               Do_Ovflow_Check := False;

            --  Despite the comments above, it is worth dealing specially with
            --  division. The only case where integer division can overflow is
            --  (largest negative number) / (-1). So we will do an extra range
            --  analysis to see if this is possible.

            elsif Nkind (N) = N_Op_Divide then
               Determine_Range
                 (Left_Opnd (N), OK, Lo, Hi, Assume_Valid => True);

               if OK and then Lo > Expr_Value (Type_Low_Bound (Typ)) then
                  Do_Ovflow_Check := False;

               else
                  Determine_Range
                    (Right_Opnd (N), OK, Lo, Hi, Assume_Valid => True);

                  if OK and then (Lo > Uint_Minus_1
                                    or else
                                  Hi < Uint_Minus_1)
                  then
                     Do_Ovflow_Check := False;
                  end if;
               end if;

            --  Likewise for Abs/Minus, the only case where the operation can
            --  overflow is when the operand is the largest negative number.

            elsif Nkind (N) in N_Op_Abs | N_Op_Minus then
               Determine_Range
                 (Right_Opnd (N), OK, Lo, Hi, Assume_Valid => True);

               if OK and then Lo > Expr_Value (Type_Low_Bound (Typ)) then
                  Do_Ovflow_Check := False;
               end if;
            end if;

            --  If no overflow check required, we are done

            if not Do_Ovflow_Check then
               if Debug_Flag_CC then
                  w ("No overflow check required");
               end if;

               return;
            end if;
         end if;
      end if;

      --  If not in optimizing mode, set flag and we are done. We are also done
      --  (and just set the flag) if the type is not a discrete type, since it
      --  is not worth the effort to eliminate checks for other than discrete
      --  types. In addition, we take this same path if we have stored the
      --  maximum number of checks possible already (a very unlikely situation,
      --  but we do not want to blow up).

      if Optimization_Level = 0
        or else not Is_Discrete_Type (Etype (N))
        or else Num_Saved_Checks = Saved_Checks'Last
      then
         Activate_Overflow_Check (N);

         if Debug_Flag_CC then
            w ("Optimization off");
         end if;

         return;
      end if;

      --  Otherwise evaluate and check the expression

      Find_Check
        (Expr        => N,
         Check_Type  => 'O',
         Target_Type => Empty,
         Entry_OK    => OK,
         Check_Num   => Chk,
         Ent         => Ent,
         Ofs         => Ofs);

      if Debug_Flag_CC then
         w ("Called Find_Check");
         w ("  OK = ", OK);

         if OK then
            w ("  Check_Num = ", Chk);
            w ("  Ent       = ", Int (Ent));
            Write_Str ("  Ofs       = ");
            pid (Ofs);
         end if;
      end if;

      --  If check is not of form to optimize, then set flag and we are done

      if not OK then
         Activate_Overflow_Check (N);
         return;
      end if;

      --  If check is already performed, then return without setting flag

      if Chk /= 0 then
         if Debug_Flag_CC then
            w ("Check suppressed!");
         end if;

         return;
      end if;

      --  Here we will make a new entry for the new check

      Activate_Overflow_Check (N);
      Num_Saved_Checks := Num_Saved_Checks + 1;
      Saved_Checks (Num_Saved_Checks) :=
        (Killed      => False,
         Entity      => Ent,
         Offset      => Ofs,
         Check_Type  => 'O',
         Target_Type => Empty);

      if Debug_Flag_CC then
         w ("Make new entry, check number = ", Num_Saved_Checks);
         w ("  Entity = ", Int (Ent));
         Write_Str ("  Offset = ");
         pid (Ofs);
         w ("  Check_Type = O");
         w ("  Target_Type = Empty");
      end if;

   --  If we get an exception, then something went wrong, probably because of
   --  an error in the structure of the tree due to an incorrect program. Or
   --  it may be a bug in the optimization circuit. In either case the safest
   --  thing is simply to set the check flag unconditionally.

   exception
      when others =>
         Activate_Overflow_Check (N);

         if Debug_Flag_CC then
            w ("  exception occurred, overflow flag set");
         end if;

         return;
   end Enable_Overflow_Check;

   ------------------------
   -- Enable_Range_Check --
   ------------------------

   procedure Enable_Range_Check (N : Node_Id) is
      Chk  : Nat;
      OK   : Boolean;
      Ent  : Entity_Id;
      Ofs  : Uint;
      Ttyp : Entity_Id;
      P    : Node_Id;

   begin
      --  Return if unchecked type conversion with range check killed. In this
      --  case we never set the flag (that's what Kill_Range_Check is about).

      if Nkind (N) = N_Unchecked_Type_Conversion
        and then Kill_Range_Check (N)
      then
         return;
      end if;

      --  Do not set range check flag if parent is assignment statement or
      --  object declaration with Suppress_Assignment_Checks flag set

      if Nkind (Parent (N)) in N_Assignment_Statement | N_Object_Declaration
        and then Suppress_Assignment_Checks (Parent (N))
      then
         return;
      end if;

      --  Check for various cases where we should suppress the range check

      --  No check if range checks suppressed for type of node

      if Present (Etype (N)) and then Range_Checks_Suppressed (Etype (N)) then
         return;

      --  No check if node is an entity name, and range checks are suppressed
      --  for this entity, or for the type of this entity.

      elsif Is_Entity_Name (N)
        and then (Range_Checks_Suppressed (Entity (N))
                   or else Range_Checks_Suppressed (Etype (Entity (N))))
      then
         return;

      --  No checks if index of array, and index checks are suppressed for
      --  the array object or the type of the array.

      elsif Nkind (Parent (N)) = N_Indexed_Component then
         declare
            Pref : constant Node_Id := Prefix (Parent (N));
         begin
            if Is_Entity_Name (Pref)
              and then Index_Checks_Suppressed (Entity (Pref))
            then
               return;
            elsif Index_Checks_Suppressed (Etype (Pref)) then
               return;
            end if;
         end;
      end if;

      --  Debug trace output

      if Debug_Flag_CC then
         w ("Enable_Range_Check for node ", Int (N));
         Write_Str ("  Source location = ");
         wl (Sloc (N));
         pg (Union_Id (N));
      end if;

      --  If not in optimizing mode, set flag and we are done. We are also done
      --  (and just set the flag) if the type is not a discrete type, since it
      --  is not worth the effort to eliminate checks for other than discrete
      --  types. In addition, we take this same path if we have stored the
      --  maximum number of checks possible already (a very unlikely situation,
      --  but we do not want to blow up).

      if Optimization_Level = 0
        or else No (Etype (N))
        or else not Is_Discrete_Type (Etype (N))
        or else Num_Saved_Checks = Saved_Checks'Last
      then
         Activate_Range_Check (N);

         if Debug_Flag_CC then
            w ("Optimization off");
         end if;

         return;
      end if;

      --  Otherwise find out the target type

      P := Parent (N);

      --  For assignment, use left side subtype

      if Nkind (P) = N_Assignment_Statement
        and then Expression (P) = N
      then
         Ttyp := Etype (Name (P));

      --  For indexed component, use subscript subtype

      elsif Nkind (P) = N_Indexed_Component then
         declare
            Atyp : Entity_Id;
            Indx : Node_Id;
            Subs : Node_Id;

         begin
            Atyp := Etype (Prefix (P));

            if Is_Access_Type (Atyp) then
               Atyp := Designated_Type (Atyp);

               --  If the prefix is an access to an unconstrained array,
               --  perform check unconditionally: it depends on the bounds of
               --  an object and we cannot currently recognize whether the test
               --  may be redundant.

               if not Is_Constrained (Atyp) then
                  Activate_Range_Check (N);
                  return;
               end if;

            --  Ditto if prefix is simply an unconstrained array. We used
            --  to think this case was OK, if the prefix was not an explicit
            --  dereference, but we have now seen a case where this is not
            --  true, so it is safer to just suppress the optimization in this
            --  case. The back end is getting better at eliminating redundant
            --  checks in any case, so the loss won't be important.

            elsif Is_Array_Type (Atyp)
              and then not Is_Constrained (Atyp)
            then
               Activate_Range_Check (N);
               return;
            end if;

            Indx := First_Index (Atyp);
            Subs := First (Expressions (P));
            loop
               if Subs = N then
                  Ttyp := Etype (Indx);
                  exit;
               end if;

               Next_Index (Indx);
               Next (Subs);
            end loop;
         end;

      --  For now, ignore all other cases, they are not so interesting

      else
         if Debug_Flag_CC then
            w ("  target type not found, flag set");
         end if;

         Activate_Range_Check (N);
         return;
      end if;

      --  Evaluate and check the expression

      Find_Check
        (Expr        => N,
         Check_Type  => 'R',
         Target_Type => Ttyp,
         Entry_OK    => OK,
         Check_Num   => Chk,
         Ent         => Ent,
         Ofs         => Ofs);

      if Debug_Flag_CC then
         w ("Called Find_Check");
         w ("Target_Typ = ", Int (Ttyp));
         w ("  OK = ", OK);

         if OK then
            w ("  Check_Num = ", Chk);
            w ("  Ent       = ", Int (Ent));
            Write_Str ("  Ofs       = ");
            pid (Ofs);
         end if;
      end if;

      --  If check is not of form to optimize, then set flag and we are done

      if not OK then
         if Debug_Flag_CC then
            w ("  expression not of optimizable type, flag set");
         end if;

         Activate_Range_Check (N);
         return;
      end if;

      --  If check is already performed, then return without setting flag

      if Chk /= 0 then
         if Debug_Flag_CC then
            w ("Check suppressed!");
         end if;

         return;
      end if;

      --  Here we will make a new entry for the new check

      Activate_Range_Check (N);
      Num_Saved_Checks := Num_Saved_Checks + 1;
      Saved_Checks (Num_Saved_Checks) :=
        (Killed      => False,
         Entity      => Ent,
         Offset      => Ofs,
         Check_Type  => 'R',
         Target_Type => Ttyp);

      if Debug_Flag_CC then
         w ("Make new entry, check number = ", Num_Saved_Checks);
         w ("  Entity = ", Int (Ent));
         Write_Str ("  Offset = ");
         pid (Ofs);
         w ("  Check_Type = R");
         w ("  Target_Type = ", Int (Ttyp));
         pg (Union_Id (Ttyp));
      end if;

   --  If we get an exception, then something went wrong, probably because of
   --  an error in the structure of the tree due to an incorrect program. Or
   --  it may be a bug in the optimization circuit. In either case the safest
   --  thing is simply to set the check flag unconditionally.

   exception
      when others =>
         Activate_Range_Check (N);

         if Debug_Flag_CC then
            w ("  exception occurred, range flag set");
         end if;

         return;
   end Enable_Range_Check;

   ------------------
   -- Ensure_Valid --
   ------------------

   procedure Ensure_Valid
     (Expr          : Node_Id;
      Holes_OK      : Boolean   := False;
      Related_Id    : Entity_Id := Empty;
      Is_Low_Bound  : Boolean   := False;
      Is_High_Bound : Boolean   := False)
   is
      Typ : constant Entity_Id  := Etype (Expr);

   begin
      --  Ignore call if we are not doing any validity checking

      if not Validity_Checks_On then
         return;

      --  Ignore call if range or validity checks suppressed on entity or type

      elsif Range_Or_Validity_Checks_Suppressed (Expr) then
         return;

      --  No check required if expression is from the expander, we assume the
      --  expander will generate whatever checks are needed. Note that this is
      --  not just an optimization, it avoids infinite recursions.

      --  Unchecked conversions must be checked, unless they are initialized
      --  scalar values, as in a component assignment in an init proc.

      --  In addition, we force a check if Force_Validity_Checks is set

      elsif not Comes_From_Source (Expr)
        and then not
          (Nkind (Expr) = N_Identifier
            and then Present (Renamed_Object (Entity (Expr)))
            and then Comes_From_Source (Renamed_Object (Entity (Expr))))
        and then not Force_Validity_Checks
        and then (Nkind (Expr) /= N_Unchecked_Type_Conversion
                    or else Kill_Range_Check (Expr))
      then
         return;

      --  No check required if expression is known to have valid value

      elsif Expr_Known_Valid (Expr) then
         return;

      --  No check needed within a generated predicate function. Validity
      --  of input value will have been checked earlier.

      elsif Ekind (Current_Scope) = E_Function
        and then Is_Predicate_Function (Current_Scope)
      then
         return;

      --  Ignore case of enumeration with holes where the flag is set not to
      --  worry about holes, since no special validity check is needed

      elsif Is_Enumeration_Type (Typ)
        and then Has_Non_Standard_Rep (Typ)
        and then Holes_OK
      then
         return;

      --  No check required on the left-hand side of an assignment

      elsif Nkind (Parent (Expr)) = N_Assignment_Statement
        and then Expr = Name (Parent (Expr))
      then
         return;

      --  No check on a universal real constant. The context will eventually
      --  convert it to a machine number for some target type, or report an
      --  illegality.

      elsif Nkind (Expr) = N_Real_Literal
        and then Etype (Expr) = Universal_Real
      then
         return;

      --  If the expression denotes a component of a packed boolean array,
      --  no possible check applies. We ignore the old ACATS chestnuts that
      --  involve Boolean range True..True.

      --  Note: validity checks are generated for expressions that yield a
      --  scalar type, when it is possible to create a value that is outside of
      --  the type. If this is a one-bit boolean no such value exists. This is
      --  an optimization, and it also prevents compiler blowing up during the
      --  elaboration of improperly expanded packed array references.

      elsif Nkind (Expr) = N_Indexed_Component
        and then Is_Bit_Packed_Array (Etype (Prefix (Expr)))
        and then Root_Type (Etype (Expr)) = Standard_Boolean
      then
         return;

      --  For an expression with actions, we want to insert the validity check
      --  on the final Expression.

      elsif Nkind (Expr) = N_Expression_With_Actions then
         Ensure_Valid (Expression (Expr));
         return;

      --  An annoying special case. If this is an out parameter of a scalar
      --  type, then the value is not going to be accessed, therefore it is
      --  inappropriate to do any validity check at the call site. Likewise
      --  if the parameter is passed by reference.

      else
         --  Only need to worry about scalar types

         if Is_Scalar_Type (Typ) then
            declare
               P : Node_Id;
               N : Node_Id;
               E : Entity_Id;
               F : Entity_Id;
               A : Node_Id;
               L : List_Id;

            begin
               --  Find actual argument (which may be a parameter association)
               --  and the parent of the actual argument (the call statement)

               N := Expr;
               P := Parent (Expr);

               if Nkind (P) = N_Parameter_Association then
                  N := P;
                  P := Parent (N);
               end if;

               --  If this is an indirect or dispatching call, get signature
               --  from the subprogram type.

               if Nkind (P) in N_Entry_Call_Statement
                             | N_Function_Call
                             | N_Procedure_Call_Statement
               then
                  E := Get_Called_Entity (P);
                  L := Parameter_Associations (P);

                  --  Only need to worry if there are indeed actuals, and if
                  --  this could be a subprogram call, otherwise we cannot get
                  --  a match (either we are not an argument, or the mode of
                  --  the formal is not OUT). This test also filters out the
                  --  generic case.

                  if Is_Non_Empty_List (L) and then Is_Subprogram (E) then

                     --  This is the loop through parameters, looking for an
                     --  OUT parameter for which we are the argument.

                     F := First_Formal (E);
                     A := First (L);
                     while Present (F) loop
                        if A = N
                          and then (Ekind (F) = E_Out_Parameter
                                     or else Mechanism (F) = By_Reference)
                        then
                           return;
                        end if;

                        Next_Formal (F);
                        Next (A);
                     end loop;
                  end if;
               end if;
            end;
         end if;
      end if;

      --  If this is a boolean expression, only its elementary operands need
      --  checking: if they are valid, a boolean or short-circuit operation
      --  with them will be valid as well.

      if Base_Type (Typ) = Standard_Boolean
        and then
         (Nkind (Expr) in N_Op or else Nkind (Expr) in N_Short_Circuit)
      then
         return;
      end if;

      --  If we fall through, a validity check is required

      Insert_Valid_Check (Expr, Related_Id, Is_Low_Bound, Is_High_Bound);

      if Is_Entity_Name (Expr)
        and then Safe_To_Capture_Value (Expr, Entity (Expr))
      then
         Set_Is_Known_Valid (Entity (Expr));
      end if;
   end Ensure_Valid;

   ----------------------
   -- Expr_Known_Valid --
   ----------------------

   function Expr_Known_Valid (Expr : Node_Id) return Boolean is
      Typ : constant Entity_Id := Etype (Expr);

   begin
      --  Non-scalar types are always considered valid, since they never give
      --  rise to the issues of erroneous or bounded error behavior that are
      --  the concern. In formal reference manual terms the notion of validity
      --  only applies to scalar types. Note that even when packed arrays are
      --  represented using modular types, they are still arrays semantically,
      --  so they are also always valid (in particular, the unused bits can be
      --  random rubbish without affecting the validity of the array value).

      if not Is_Scalar_Type (Typ) or else Is_Packed_Array_Impl_Type (Typ) then
         return True;

      --  If no validity checking, then everything is considered valid

      elsif not Validity_Checks_On then
         return True;

      --  Floating-point types are considered valid unless floating-point
      --  validity checks have been specifically turned on.

      elsif Is_Floating_Point_Type (Typ)
        and then not Validity_Check_Floating_Point
      then
         return True;

      --  If the expression is the value of an object that is known to be
      --  valid, then clearly the expression value itself is valid.

      elsif Is_Entity_Name (Expr)
        and then Is_Known_Valid (Entity (Expr))

        --  Exclude volatile variables

        and then not Treat_As_Volatile (Entity (Expr))
      then
         return True;

      --  References to discriminants are always considered valid. The value
      --  of a discriminant gets checked when the object is built. Within the
      --  record, we consider it valid, and it is important to do so, since
      --  otherwise we can try to generate bogus validity checks which
      --  reference discriminants out of scope. Discriminants of concurrent
      --  types are excluded for the same reason.

      elsif Is_Entity_Name (Expr)
        and then Denotes_Discriminant (Expr, Check_Concurrent => True)
      then
         return True;

      --  If the type is one for which all values are known valid, then we are
      --  sure that the value is valid except in the slightly odd case where
      --  the expression is a reference to a variable whose size has been
      --  explicitly set to a value greater than the object size.

      elsif Is_Known_Valid (Typ) then
         if Is_Entity_Name (Expr)
           and then Ekind (Entity (Expr)) = E_Variable
           and then Known_Esize (Entity (Expr))
           and then Esize (Entity (Expr)) > Esize (Typ)
         then
            return False;
         else
            return True;
         end if;

      --  Integer and character literals always have valid values, where
      --  appropriate these will be range checked in any case.

      elsif Nkind (Expr) in N_Integer_Literal | N_Character_Literal then
         return True;

      --  If we have a type conversion or a qualification of a known valid
      --  value, then the result will always be valid.

      elsif Nkind (Expr) in N_Type_Conversion | N_Qualified_Expression then
         return Expr_Known_Valid (Expression (Expr));

      --  Case of expression is a non-floating-point operator. In this case we
      --  can assume the result is valid the generated code for the operator
      --  will include whatever checks are needed (e.g. range checks) to ensure
      --  validity. This assumption does not hold for the floating-point case,
      --  since floating-point operators can generate Infinite or NaN results
      --  which are considered invalid.

      --  Historical note: in older versions, the exemption of floating-point
      --  types from this assumption was done only in cases where the parent
      --  was an assignment, function call or parameter association. Presumably
      --  the idea was that in other contexts, the result would be checked
      --  elsewhere, but this list of cases was missing tests (at least the
      --  N_Object_Declaration case, as shown by a reported missing validity
      --  check), and it is not clear why function calls but not procedure
      --  calls were tested for. It really seems more accurate and much
      --  safer to recognize that expressions which are the result of a
      --  floating-point operator can never be assumed to be valid.

      elsif Nkind (Expr) in N_Op and then not Is_Floating_Point_Type (Typ) then
         return True;

      --  The result of a membership test is always valid, since it is true or
      --  false, there are no other possibilities.

      elsif Nkind (Expr) in N_Membership_Test then
         return True;

      --  For all other cases, we do not know the expression is valid

      else
         return False;
      end if;
   end Expr_Known_Valid;

   ----------------
   -- Find_Check --
   ----------------

   procedure Find_Check
     (Expr        : Node_Id;
      Check_Type  : Character;
      Target_Type : Entity_Id;
      Entry_OK    : out Boolean;
      Check_Num   : out Nat;
      Ent         : out Entity_Id;
      Ofs         : out Uint)
   is
      function Within_Range_Of
        (Target_Type : Entity_Id;
         Check_Type  : Entity_Id) return Boolean;
      --  Given a requirement for checking a range against Target_Type, and
      --  and a range Check_Type against which a check has already been made,
      --  determines if the check against check type is sufficient to ensure
      --  that no check against Target_Type is required.

      ---------------------
      -- Within_Range_Of --
      ---------------------

      function Within_Range_Of
        (Target_Type : Entity_Id;
         Check_Type  : Entity_Id) return Boolean
      is
      begin
         if Target_Type = Check_Type then
            return True;

         else
            declare
               Tlo : constant Node_Id := Type_Low_Bound  (Target_Type);
               Thi : constant Node_Id := Type_High_Bound (Target_Type);
               Clo : constant Node_Id := Type_Low_Bound  (Check_Type);
               Chi : constant Node_Id := Type_High_Bound (Check_Type);

            begin
               if (Tlo = Clo
                     or else (Compile_Time_Known_Value (Tlo)
                                and then
                              Compile_Time_Known_Value (Clo)
                                and then
                              Expr_Value (Clo) >= Expr_Value (Tlo)))
                 and then
                  (Thi = Chi
                     or else (Compile_Time_Known_Value (Thi)
                                and then
                              Compile_Time_Known_Value (Chi)
                                and then
                              Expr_Value (Chi) <= Expr_Value (Clo)))
               then
                  return True;
               else
                  return False;
               end if;
            end;
         end if;
      end Within_Range_Of;

   --  Start of processing for Find_Check

   begin
      --  Establish default, in case no entry is found

      Check_Num := 0;

      --  Case of expression is simple entity reference

      if Is_Entity_Name (Expr) then
         Ent := Entity (Expr);
         Ofs := Uint_0;

      --  Case of expression is entity + known constant

      elsif Nkind (Expr) = N_Op_Add
        and then Compile_Time_Known_Value (Right_Opnd (Expr))
        and then Is_Entity_Name (Left_Opnd (Expr))
      then
         Ent := Entity (Left_Opnd (Expr));
         Ofs := Expr_Value (Right_Opnd (Expr));

      --  Case of expression is entity - known constant

      elsif Nkind (Expr) = N_Op_Subtract
        and then Compile_Time_Known_Value (Right_Opnd (Expr))
        and then Is_Entity_Name (Left_Opnd (Expr))
      then
         Ent := Entity (Left_Opnd (Expr));
         Ofs := UI_Negate (Expr_Value (Right_Opnd (Expr)));

      --  Any other expression is not of the right form

      else
         Ent := Empty;
         Ofs := Uint_0;
         Entry_OK := False;
         return;
      end if;

      --  Come here with expression of appropriate form, check if entity is an
      --  appropriate one for our purposes.

      if (Ekind (Ent) = E_Variable
            or else Is_Constant_Object (Ent))
        and then not Is_Library_Level_Entity (Ent)
      then
         Entry_OK := True;
      else
         Entry_OK := False;
         return;
      end if;

      --  See if there is matching check already

      for J in reverse 1 .. Num_Saved_Checks loop
         declare
            SC : Saved_Check renames Saved_Checks (J);
         begin
            if SC.Killed = False
              and then SC.Entity = Ent
              and then SC.Offset = Ofs
              and then SC.Check_Type = Check_Type
              and then Within_Range_Of (Target_Type, SC.Target_Type)
            then
               Check_Num := J;
               return;
            end if;
         end;
      end loop;

      --  If we fall through entry was not found

      return;
   end Find_Check;

   ---------------------------------
   -- Generate_Discriminant_Check --
   ---------------------------------

   procedure Generate_Discriminant_Check (N : Node_Id) is
      Loc  : constant Source_Ptr := Sloc (N);
      Pref : constant Node_Id    := Prefix (N);
      Sel  : constant Node_Id    := Selector_Name (N);

      Orig_Comp : constant Entity_Id :=
        Original_Record_Component (Entity (Sel));
      --  The original component to be checked

      Discr_Fct : constant Entity_Id :=
        Discriminant_Checking_Func (Orig_Comp);
      --  The discriminant checking function

      Discr : Entity_Id;
      --  One discriminant to be checked in the type

      Real_Discr : Entity_Id;
      --  Actual discriminant in the call

      Pref_Type : Entity_Id;
      --  Type of relevant prefix (ignoring private/access stuff)

      Args : List_Id;
      --  List of arguments for function call

      Formal : Entity_Id;
      --  Keep track of the formal corresponding to the actual we build for
      --  each discriminant, in order to be able to perform the necessary type
      --  conversions.

      Scomp : Node_Id;
      --  Selected component reference for checking function argument

   begin
      Pref_Type := Etype (Pref);

      --  Force evaluation of the prefix, so that it does not get evaluated
      --  twice (once for the check, once for the actual reference). Such a
      --  double evaluation is always a potential source of inefficiency, and
      --  is functionally incorrect in the volatile case, or when the prefix
      --  may have side effects. A nonvolatile entity or a component of a
      --  nonvolatile entity requires no evaluation.

      if Is_Entity_Name (Pref) then
         if Treat_As_Volatile (Entity (Pref)) then
            Force_Evaluation (Pref, Name_Req => True);
         end if;

      elsif Treat_As_Volatile (Etype (Pref)) then
         Force_Evaluation (Pref, Name_Req => True);

      elsif Nkind (Pref) = N_Selected_Component
        and then Is_Entity_Name (Prefix (Pref))
      then
         null;

      else
         Force_Evaluation (Pref, Name_Req => True);
      end if;

      --  For a tagged type, use the scope of the original component to
      --  obtain the type, because ???

      if Is_Tagged_Type (Scope (Orig_Comp)) then
         Pref_Type := Scope (Orig_Comp);

      --  For an untagged derived type, use the discriminants of the parent
      --  which have been renamed in the derivation, possibly by a one-to-many
      --  discriminant constraint. For untagged type, initially get the Etype
      --  of the prefix

      else
         if Is_Derived_Type (Pref_Type)
           and then Number_Discriminants (Pref_Type) /=
                    Number_Discriminants (Etype (Base_Type (Pref_Type)))
         then
            Pref_Type := Etype (Base_Type (Pref_Type));
         end if;
      end if;

      --  We definitely should have a checking function, This routine should
      --  not be called if no discriminant checking function is present.

      pragma Assert (Present (Discr_Fct));

      --  Create the list of the actual parameters for the call. This list
      --  is the list of the discriminant fields of the record expression to
      --  be discriminant checked.

      Args   := New_List;
      Formal := First_Formal (Discr_Fct);
      Discr  := First_Discriminant (Pref_Type);
      while Present (Discr) loop

         --  If we have a corresponding discriminant field, and a parent
         --  subtype is present, then we want to use the corresponding
         --  discriminant since this is the one with the useful value.

         if Present (Corresponding_Discriminant (Discr))
           and then Ekind (Pref_Type) = E_Record_Type
           and then Present (Parent_Subtype (Pref_Type))
         then
            Real_Discr := Corresponding_Discriminant (Discr);
         else
            Real_Discr := Discr;
         end if;

         --  Construct the reference to the discriminant

         Scomp :=
           Make_Selected_Component (Loc,
             Prefix =>
               Unchecked_Convert_To (Pref_Type,
                 Duplicate_Subexpr (Pref)),
             Selector_Name => New_Occurrence_Of (Real_Discr, Loc));

         --  Manually analyze and resolve this selected component. We really
         --  want it just as it appears above, and do not want the expander
         --  playing discriminal games etc with this reference. Then we append
         --  the argument to the list we are gathering.

         Set_Etype (Scomp, Etype (Real_Discr));
         Set_Analyzed (Scomp, True);
         Append_To (Args, Convert_To (Etype (Formal), Scomp));

         Next_Formal_With_Extras (Formal);
         Next_Discriminant (Discr);
      end loop;

      --  Now build and insert the call

      Insert_Action (N,
        Make_Raise_Constraint_Error (Loc,
          Condition =>
            Make_Function_Call (Loc,
              Name                   => New_Occurrence_Of (Discr_Fct, Loc),
              Parameter_Associations => Args),
          Reason => CE_Discriminant_Check_Failed));
   end Generate_Discriminant_Check;

   ---------------------------
   -- Generate_Index_Checks --
   ---------------------------

   procedure Generate_Index_Checks
     (N                : Node_Id;
      Checks_Generated : out Dimension_Set)
   is

      function Entity_Of_Prefix return Entity_Id;
      --  Returns the entity of the prefix of N (or Empty if not found)

      ----------------------
      -- Entity_Of_Prefix --
      ----------------------

      function Entity_Of_Prefix return Entity_Id is
         P : Node_Id;

      begin
         P := Prefix (N);
         while not Is_Entity_Name (P) loop
            if Nkind (P) not in N_Selected_Component | N_Indexed_Component then
               return Empty;
            end if;

            P := Prefix (P);
         end loop;

         return Entity (P);
      end Entity_Of_Prefix;

      --  Local variables

      Loc   : constant Source_Ptr := Sloc (N);
      A     : constant Node_Id    := Prefix (N);
      A_Ent : constant Entity_Id  := Entity_Of_Prefix;
      Sub   : Node_Id;

   --  Start of processing for Generate_Index_Checks

   begin
      Checks_Generated.Elements := (others => False);

      --  Ignore call if the prefix is not an array since we have a serious
      --  error in the sources. Ignore it also if index checks are suppressed
      --  for array object or type.

      if not Is_Array_Type (Etype (A))
        or else (Present (A_Ent) and then Index_Checks_Suppressed (A_Ent))
        or else Index_Checks_Suppressed (Etype (A))
      then
         return;

      --  The indexed component we are dealing with contains 'Loop_Entry in its
      --  prefix. This case arises when analysis has determined that constructs
      --  such as

      --     Prefix'Loop_Entry (Expr)
      --     Prefix'Loop_Entry (Expr1, Expr2, ... ExprN)

      --  require rewriting for error detection purposes. A side effect of this
      --  action is the generation of index checks that mention 'Loop_Entry.
      --  Delay the generation of the check until 'Loop_Entry has been properly
      --  expanded. This is done in Expand_Loop_Entry_Attributes.

      elsif Nkind (Prefix (N)) = N_Attribute_Reference
        and then Attribute_Name (Prefix (N)) = Name_Loop_Entry
      then
         return;
      end if;

      --  Generate a raise of constraint error with the appropriate reason and
      --  a condition of the form:

      --    Base_Type (Sub) not in Array'Range (Subscript)

      --  Note that the reason we generate the conversion to the base type here
      --  is that we definitely want the range check to take place, even if it
      --  looks like the subtype is OK. Optimization considerations that allow
      --  us to omit the check have already been taken into account in the
      --  setting of the Do_Range_Check flag earlier on.

      Sub := First (Expressions (N));

      --  Handle string literals

      if Ekind (Etype (A)) = E_String_Literal_Subtype then
         if Do_Range_Check (Sub) then
            Set_Do_Range_Check (Sub, False);

            --  For string literals we obtain the bounds of the string from the
            --  associated subtype.

            Insert_Action (N,
              Make_Raise_Constraint_Error (Loc,
                Condition =>
                   Make_Not_In (Loc,
                     Left_Opnd  =>
                       Convert_To (Base_Type (Etype (Sub)),
                         Duplicate_Subexpr_Move_Checks (Sub)),
                     Right_Opnd =>
                       Make_Attribute_Reference (Loc,
                         Prefix         => New_Occurrence_Of (Etype (A), Loc),
                         Attribute_Name => Name_Range)),
                Reason => CE_Index_Check_Failed));

            Checks_Generated.Elements (1) := True;
         end if;

      --  General case

      else
         declare
            A_Idx   : Node_Id;
            A_Range : Node_Id;
            Ind     : Pos;
            Num     : List_Id;
            Range_N : Node_Id;

         begin
            A_Idx := First_Index (Etype (A));
            Ind   := 1;
            while Present (Sub) loop
               if Do_Range_Check (Sub) then
                  Set_Do_Range_Check (Sub, False);

                  --  Force evaluation except for the case of a simple name of
                  --  a nonvolatile entity.

                  if not Is_Entity_Name (Sub)
                    or else Treat_As_Volatile (Entity (Sub))
                  then
                     Force_Evaluation (Sub);
                  end if;

                  if Nkind (A_Idx) = N_Range then
                     A_Range := A_Idx;

                  elsif Nkind (A_Idx) in N_Identifier | N_Expanded_Name then
                     A_Range := Scalar_Range (Entity (A_Idx));

                     if Nkind (A_Range) = N_Subtype_Indication then
                        A_Range := Range_Expression (Constraint (A_Range));
                     end if;

                  else pragma Assert (Nkind (A_Idx) = N_Subtype_Indication);
                     A_Range := Range_Expression (Constraint (A_Idx));
                  end if;

                  --  For array objects with constant bounds we can generate
                  --  the index check using the bounds of the type of the index

                  if Present (A_Ent)
                    and then Ekind (A_Ent) = E_Variable
                    and then Is_Constant_Bound (Low_Bound (A_Range))
                    and then Is_Constant_Bound (High_Bound (A_Range))
                  then
                     Range_N :=
                       Make_Attribute_Reference (Loc,
                         Prefix         =>
                           New_Occurrence_Of (Etype (A_Idx), Loc),
                         Attribute_Name => Name_Range);

                  --  For arrays with non-constant bounds we cannot generate
                  --  the index check using the bounds of the type of the index
                  --  since it may reference discriminants of some enclosing
                  --  type. We obtain the bounds directly from the prefix
                  --  object.

                  else
                     if Ind = 1 then
                        Num := No_List;
                     else
                        Num := New_List (Make_Integer_Literal (Loc, Ind));
                     end if;

                     Range_N :=
                       Make_Attribute_Reference (Loc,
                         Prefix =>
                           Duplicate_Subexpr_Move_Checks (A, Name_Req => True),
                         Attribute_Name => Name_Range,
                         Expressions    => Num);
                  end if;

                  Insert_Action (N,
                    Make_Raise_Constraint_Error (Loc,
                      Condition =>
                         Make_Not_In (Loc,
                           Left_Opnd  =>
                             Convert_To (Base_Type (Etype (Sub)),
                               Duplicate_Subexpr_Move_Checks (Sub)),
                           Right_Opnd => Range_N),
                      Reason => CE_Index_Check_Failed));

                  Checks_Generated.Elements (Ind) := True;
               end if;

               Next_Index (A_Idx);
               Ind := Ind + 1;
               Next (Sub);
            end loop;
         end;
      end if;
   end Generate_Index_Checks;

   --------------------------
   -- Generate_Range_Check --
   --------------------------

   procedure Generate_Range_Check
     (N           : Node_Id;
      Target_Type : Entity_Id;
      Reason      : RT_Exception_Code)
   is
      Loc              : constant Source_Ptr := Sloc (N);
      Source_Type      : constant Entity_Id  := Etype (N);
      Source_Base_Type : constant Entity_Id  := Base_Type (Source_Type);
      Target_Base_Type : constant Entity_Id  := Base_Type (Target_Type);

      procedure Convert_And_Check_Range (Suppress : Check_Id);
      --  Convert N to the target base type and save the result in a temporary.
      --  The action is analyzed using the default checks as modified by the
      --  given Suppress argument. Then check the converted value against the
      --  range of the target subtype.

      function Is_Single_Attribute_Reference (N : Node_Id) return Boolean;
      --  Return True if N is an expression that contains a single attribute
      --  reference, possibly as operand among only integer literal operands.

      -----------------------------
      -- Convert_And_Check_Range --
      -----------------------------

      procedure Convert_And_Check_Range (Suppress : Check_Id) is
         Tnn    : constant Entity_Id := Make_Temporary (Loc, 'T', N);
         Conv_N : Node_Id;

      begin
         --  For enumeration types with non-standard representation this is a
         --  direct conversion from the enumeration type to the target integer
         --  type, which is treated by the back end as a normal integer type
         --  conversion, treating the enumeration type as an integer, which is
         --  exactly what we want. We set Conversion_OK to make sure that the
         --  analyzer does not complain about what otherwise might be an
         --  illegal conversion.

         if Is_Enumeration_Type (Source_Base_Type)
           and then Present (Enum_Pos_To_Rep (Source_Base_Type))
           and then Is_Integer_Type (Target_Base_Type)
         then
            Conv_N := OK_Convert_To (Target_Base_Type, Duplicate_Subexpr (N));
         else
            Conv_N := Convert_To (Target_Base_Type, Duplicate_Subexpr (N));
         end if;

         --  We make a temporary to hold the value of the conversion to the
         --  target base type, and then do the test against this temporary.
         --  N itself is replaced by an occurrence of Tnn and followed by
         --  the explicit range check.

         --     Tnn : constant Target_Base_Type := Target_Base_Type (N);
         --     [constraint_error when Tnn not in Target_Type]
         --     Tnn

         Insert_Actions (N, New_List (
           Make_Object_Declaration (Loc,
             Defining_Identifier => Tnn,
             Object_Definition   => New_Occurrence_Of (Target_Base_Type, Loc),
             Constant_Present    => True,
             Expression          => Conv_N),

           Make_Raise_Constraint_Error (Loc,
             Condition =>
               Make_Not_In (Loc,
                 Left_Opnd  => New_Occurrence_Of (Tnn, Loc),
                 Right_Opnd => New_Occurrence_Of (Target_Type, Loc)),
             Reason => Reason)),
           Suppress => Suppress);

         Rewrite (N, New_Occurrence_Of (Tnn, Loc));

         --  Set the type of N, because the declaration for Tnn might not
         --  be analyzed yet, as is the case if N appears within a record
         --  declaration, as a discriminant constraint or expression.

         Set_Etype (N, Target_Base_Type);
      end Convert_And_Check_Range;

      -------------------------------------
      --  Is_Single_Attribute_Reference  --
      -------------------------------------

      function Is_Single_Attribute_Reference (N : Node_Id) return Boolean is
      begin
         if Nkind (N) = N_Attribute_Reference then
            return True;

         elsif Nkind (N) in N_Binary_Op then
            if Nkind (Right_Opnd (N)) = N_Integer_Literal then
               return Is_Single_Attribute_Reference (Left_Opnd (N));

            elsif Nkind (Left_Opnd (N)) = N_Integer_Literal then
               return Is_Single_Attribute_Reference (Right_Opnd (N));

            else
               return False;
            end if;

         else
            return False;
         end if;
      end Is_Single_Attribute_Reference;

   --  Start of processing for Generate_Range_Check

   begin
      --  First special case, if the source type is already within the range
      --  of the target type, then no check is needed (probably we should have
      --  stopped Do_Range_Check from being set in the first place, but better
      --  late than never in preventing junk code and junk flag settings).

      if In_Subrange_Of (Source_Type, Target_Type)

        --  We do NOT apply this if the source node is a literal, since in this
        --  case the literal has already been labeled as having the subtype of
        --  the target.

        and then not
          (Nkind (N) in
               N_Integer_Literal | N_Real_Literal | N_Character_Literal
             or else
               (Is_Entity_Name (N)
                 and then Ekind (Entity (N)) = E_Enumeration_Literal))
      then
         Set_Do_Range_Check (N, False);
         return;
      end if;

      --  Here a check is needed. If the expander is not active (which is also
      --  the case in GNATprove mode), then simply set the Do_Range_Check flag
      --  and we are done. We just want to see the range check flag set, we do
      --  not want to generate the explicit range check code.

      if not Expander_Active then
         Set_Do_Range_Check (N);
         return;
      end if;

      --  Here we will generate an explicit range check, so we don't want to
      --  set the Do_Range check flag, since the range check is taken care of
      --  by the code we will generate.

      Set_Do_Range_Check (N, False);

      --  Force evaluation of the node, so that it does not get evaluated twice
      --  (once for the check, once for the actual reference). Such a double
      --  evaluation is always a potential source of inefficiency, and is
      --  functionally incorrect in the volatile case.

      --  We skip the evaluation of attribute references because, after these
      --  runtime checks are generated, the expander may need to rewrite this
      --  node (for example, see Attribute_Max_Size_In_Storage_Elements in
      --  Expand_N_Attribute_Reference) and, in many cases, their return type
      --  is universal integer, which is a very large type for a temporary.

      if not Is_Single_Attribute_Reference (N)
        and then (not Is_Entity_Name (N)
                   or else Treat_As_Volatile (Entity (N)))
      then
         Force_Evaluation (N, Mode => Strict);
      end if;

      --  The easiest case is when Source_Base_Type and Target_Base_Type are
      --  the same since in this case we can simply do a direct check of the
      --  value of N against the bounds of Target_Type.

      --    [constraint_error when N not in Target_Type]

      --  Note: this is by far the most common case, for example all cases of
      --  checks on the RHS of assignments are in this category, but not all
      --  cases are like this. Notably conversions can involve two types.

      if Source_Base_Type = Target_Base_Type then

         --  Insert the explicit range check. Note that we suppress checks for
         --  this code, since we don't want a recursive range check popping up.

         Insert_Action (N,
           Make_Raise_Constraint_Error (Loc,
             Condition =>
               Make_Not_In (Loc,
                 Left_Opnd  => Duplicate_Subexpr (N),
                 Right_Opnd => New_Occurrence_Of (Target_Type, Loc)),
             Reason => Reason),
           Suppress => All_Checks);

      --  Next test for the case where the target type is within the bounds
      --  of the base type of the source type, since in this case we can
      --  simply convert the bounds of the target type to this base type
      --  to do the test.

      --    [constraint_error when N not in
      --       Source_Base_Type (Target_Type'First)
      --         ..
      --       Source_Base_Type(Target_Type'Last))]

      --  The conversions will always work and need no check

      --  Unchecked_Convert_To is used instead of Convert_To to handle the case
      --  of converting from an enumeration value to an integer type, such as
      --  occurs for the case of generating a range check on Enum'Val(Exp)
      --  (which used to be handled by gigi). This is OK, since the conversion
      --  itself does not require a check.

      elsif In_Subrange_Of (Target_Type, Source_Base_Type) then

         --  Insert the explicit range check. Note that we suppress checks for
         --  this code, since we don't want a recursive range check popping up.

         if Is_Discrete_Type (Source_Base_Type)
              and then
            Is_Discrete_Type (Target_Base_Type)
         then
            Insert_Action (N,
              Make_Raise_Constraint_Error (Loc,
                Condition =>
                  Make_Not_In (Loc,
                    Left_Opnd  => Duplicate_Subexpr (N),

                    Right_Opnd =>
                      Make_Range (Loc,
                        Low_Bound  =>
                          Unchecked_Convert_To (Source_Base_Type,
                            Make_Attribute_Reference (Loc,
                              Prefix         =>
                                New_Occurrence_Of (Target_Type, Loc),
                              Attribute_Name => Name_First)),

                        High_Bound =>
                          Unchecked_Convert_To (Source_Base_Type,
                            Make_Attribute_Reference (Loc,
                              Prefix         =>
                                New_Occurrence_Of (Target_Type, Loc),
                              Attribute_Name => Name_Last)))),
                Reason    => Reason),
              Suppress => All_Checks);

         --  For conversions involving at least one type that is not discrete,
         --  first convert to the target base type and then generate the range
         --  check. This avoids problems with values that are close to a bound
         --  of the target type that would fail a range check when done in a
         --  larger source type before converting but pass if converted with
         --  rounding and then checked (such as in float-to-float conversions).

         --  Note that overflow checks are not suppressed for this code because
         --  we do not know whether the source type is in range of the target
         --  base type (unlike in the next case below).

         else
            Convert_And_Check_Range (Suppress => Range_Check);
         end if;

      --  Note that at this stage we know that the Target_Base_Type is not in
      --  the range of the Source_Base_Type (since even the Target_Type itself
      --  is not in this range). It could still be the case that Source_Type is
      --  in range of the target base type since we have not checked that case.

      --  If that is the case, we can freely convert the source to the target,
      --  and then test the target result against the bounds. Note that checks
      --  are suppressed for this code, since we don't want a recursive range
      --  check popping up.

      elsif In_Subrange_Of (Source_Type, Target_Base_Type) then
         Convert_And_Check_Range (Suppress => All_Checks);

      --  At this stage, we know that we have two scalar types, which are
      --  directly convertible, and where neither scalar type has a base
      --  range that is in the range of the other scalar type.

      --  The only way this can happen is with a signed and unsigned type.
      --  So test for these two cases:

      else
         --  Case of the source is unsigned and the target is signed

         if Is_Unsigned_Type (Source_Base_Type)
           and then not Is_Unsigned_Type (Target_Base_Type)
         then
            --  If the source is unsigned and the target is signed, then we
            --  know that the source is not shorter than the target (otherwise
            --  the source base type would be in the target base type range).

            --  In other words, the unsigned type is either the same size as
            --  the target, or it is larger. It cannot be smaller.

            pragma Assert
              (Esize (Source_Base_Type) >= Esize (Target_Base_Type));

            --  We only need to check the low bound if the low bound of the
            --  target type is non-negative. If the low bound of the target
            --  type is negative, then we know that we will fit fine.

            --  If the high bound of the target type is negative, then we
            --  know we have a constraint error, since we can't possibly
            --  have a negative source.

            --  With these two checks out of the way, we can do the check
            --  using the source type safely

            --  This is definitely the most annoying case.

            --    [constraint_error
            --       when (Target_Type'First >= 0
            --               and then
            --                 N < Source_Base_Type (Target_Type'First))
            --         or else Target_Type'Last < 0
            --         or else N > Source_Base_Type (Target_Type'Last)];

            --  We turn off all checks since we know that the conversions
            --  will work fine, given the guards for negative values.

            Insert_Action (N,
              Make_Raise_Constraint_Error (Loc,
                Condition =>
                  Make_Or_Else (Loc,
                    Make_Or_Else (Loc,
                      Left_Opnd =>
                        Make_And_Then (Loc,
                          Left_Opnd => Make_Op_Ge (Loc,
                            Left_Opnd =>
                              Make_Attribute_Reference (Loc,
                                Prefix =>
                                  New_Occurrence_Of (Target_Type, Loc),
                                Attribute_Name => Name_First),
                            Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),

                          Right_Opnd =>
                            Make_Op_Lt (Loc,
                              Left_Opnd => Duplicate_Subexpr (N),
                              Right_Opnd =>
                                Convert_To (Source_Base_Type,
                                  Make_Attribute_Reference (Loc,
                                    Prefix =>
                                      New_Occurrence_Of (Target_Type, Loc),
                                    Attribute_Name => Name_First)))),

                      Right_Opnd =>
                        Make_Op_Lt (Loc,
                          Left_Opnd =>
                            Make_Attribute_Reference (Loc,
                              Prefix => New_Occurrence_Of (Target_Type, Loc),
                              Attribute_Name => Name_Last),
                            Right_Opnd => Make_Integer_Literal (Loc, Uint_0))),

                    Right_Opnd =>
                      Make_Op_Gt (Loc,
                        Left_Opnd => Duplicate_Subexpr (N),
                        Right_Opnd =>
                          Convert_To (Source_Base_Type,
                            Make_Attribute_Reference (Loc,
                              Prefix => New_Occurrence_Of (Target_Type, Loc),
                              Attribute_Name => Name_Last)))),

                Reason => Reason),
              Suppress  => All_Checks);

         --  Only remaining possibility is that the source is signed and
         --  the target is unsigned.

         else
            pragma Assert (not Is_Unsigned_Type (Source_Base_Type)
                            and then Is_Unsigned_Type (Target_Base_Type));

            --  If the source is signed and the target is unsigned, then we
            --  know that the target is not shorter than the source (otherwise
            --  the target base type would be in the source base type range).

            --  In other words, the unsigned type is either the same size as
            --  the target, or it is larger. It cannot be smaller.

            --  Clearly we have an error if the source value is negative since
            --  no unsigned type can have negative values. If the source type
            --  is non-negative, then the check can be done using the target
            --  type.

            --    Tnn : constant Target_Base_Type (N) := Target_Type;

            --    [constraint_error
            --       when N < 0 or else Tnn not in Target_Type];

            --  We turn off all checks for the conversion of N to the target
            --  base type, since we generate the explicit check to ensure that
            --  the value is non-negative

            declare
               Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N);

            begin
               Insert_Actions (N, New_List (
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Tnn,
                   Object_Definition   =>
                     New_Occurrence_Of (Target_Base_Type, Loc),
                   Constant_Present    => True,
                   Expression          =>
                     Unchecked_Convert_To
                       (Target_Base_Type, Duplicate_Subexpr (N))),

                 Make_Raise_Constraint_Error (Loc,
                   Condition =>
                     Make_Or_Else (Loc,
                       Left_Opnd =>
                         Make_Op_Lt (Loc,
                           Left_Opnd  => Duplicate_Subexpr (N),
                           Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),

                       Right_Opnd =>
                         Make_Not_In (Loc,
                           Left_Opnd  => New_Occurrence_Of (Tnn, Loc),
                           Right_Opnd =>
                             New_Occurrence_Of (Target_Type, Loc))),

                   Reason     => Reason)),
                 Suppress => All_Checks);

               --  Set the Etype explicitly, because Insert_Actions may have
               --  placed the declaration in the freeze list for an enclosing
               --  construct, and thus it is not analyzed yet.

               Set_Etype (Tnn, Target_Base_Type);
               Rewrite (N, New_Occurrence_Of (Tnn, Loc));
            end;
         end if;
      end if;
   end Generate_Range_Check;

   ------------------
   -- Get_Check_Id --
   ------------------

   function Get_Check_Id (N : Name_Id) return Check_Id is
   begin
      --  For standard check name, we can do a direct computation

      if N in First_Check_Name .. Last_Check_Name then
         return Check_Id (N - (First_Check_Name - 1));

      --  For non-standard names added by pragma Check_Name, search table

      else
         for J in All_Checks + 1 .. Check_Names.Last loop
            if Check_Names.Table (J) = N then
               return J;
            end if;
         end loop;
      end if;

      --  No matching name found

      return No_Check_Id;
   end Get_Check_Id;

   ---------------------
   -- Get_Discriminal --
   ---------------------

   function Get_Discriminal (E : Entity_Id; Bound : Node_Id) return Node_Id is
      Loc : constant Source_Ptr := Sloc (E);
      D   : Entity_Id;
      Sc  : Entity_Id;

   begin
      --  The bound can be a bona fide parameter of a protected operation,
      --  rather than a prival encoded as an in-parameter.

      if No (Discriminal_Link (Entity (Bound))) then
         return Bound;
      end if;

      --  Climb the scope stack looking for an enclosing protected type. If
      --  we run out of scopes, return the bound itself.

      Sc := Scope (E);
      while Present (Sc) loop
         if Sc = Standard_Standard then
            return Bound;
         elsif Ekind (Sc) = E_Protected_Type then
            exit;
         end if;

         Sc := Scope (Sc);
      end loop;

      D := First_Discriminant (Sc);
      while Present (D) loop
         if Chars (D) = Chars (Bound) then
            return New_Occurrence_Of (Discriminal (D), Loc);
         end if;

         Next_Discriminant (D);
      end loop;

      return Bound;
   end Get_Discriminal;

   ----------------------
   -- Get_Range_Checks --
   ----------------------

   function Get_Range_Checks
     (Expr       : Node_Id;
      Target_Typ : Entity_Id;
      Source_Typ : Entity_Id := Empty;
      Warn_Node  : Node_Id   := Empty) return Check_Result
   is
   begin
      return
        Selected_Range_Checks (Expr, Target_Typ, Source_Typ, Warn_Node);
   end Get_Range_Checks;

   ------------------
   -- Guard_Access --
   ------------------

   function Guard_Access
     (Cond : Node_Id;
      Loc  : Source_Ptr;
      Expr : Node_Id) return Node_Id
   is
   begin
      if Nkind (Cond) = N_Or_Else then
         Set_Paren_Count (Cond, 1);
      end if;

      if Nkind (Expr) = N_Allocator then
         return Cond;

      else
         return
           Make_And_Then (Loc,
             Left_Opnd =>
               Make_Op_Ne (Loc,
                 Left_Opnd  => Duplicate_Subexpr_No_Checks (Expr),
                 Right_Opnd => Make_Null (Loc)),
             Right_Opnd => Cond);
      end if;
   end Guard_Access;

   -----------------------------
   -- Index_Checks_Suppressed --
   -----------------------------

   function Index_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E) and then Checks_May_Be_Suppressed (E) then
         return Is_Check_Suppressed (E, Index_Check);
      else
         return Scope_Suppress.Suppress (Index_Check);
      end if;
   end Index_Checks_Suppressed;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
   begin
      for J in Determine_Range_Cache_N'Range loop
         Determine_Range_Cache_N (J) := Empty;
      end loop;

      Check_Names.Init;

      for J in Int range 1 .. All_Checks loop
         Check_Names.Append (Name_Id (Int (First_Check_Name) + J - 1));
      end loop;
   end Initialize;

   -------------------------
   -- Insert_Range_Checks --
   -------------------------

   procedure Insert_Range_Checks
     (Checks       : Check_Result;
      Node         : Node_Id;
      Suppress_Typ : Entity_Id;
      Static_Sloc  : Source_Ptr;
      Do_Before    : Boolean    := False)
   is
      Checks_On  : constant Boolean :=
                     not Index_Checks_Suppressed (Suppress_Typ)
                       or else
                     not Range_Checks_Suppressed (Suppress_Typ);

      Check_Node : Node_Id;

   begin
      --  For now we just return if Checks_On is false, however this should be
      --  enhanced to check for an always True value in the condition and to
      --  generate a compilation warning.

      if not Expander_Active or not Checks_On then
         return;
      end if;

      for J in 1 .. 2 loop
         exit when No (Checks (J));

         if Nkind (Checks (J)) = N_Raise_Constraint_Error
           and then Present (Condition (Checks (J)))
         then
            Check_Node := Checks (J);
         else
            Check_Node :=
              Make_Raise_Constraint_Error (Static_Sloc,
                Reason => CE_Range_Check_Failed);
         end if;

         Mark_Rewrite_Insertion (Check_Node);

         if Do_Before then
            Insert_Before_And_Analyze (Node, Check_Node);
         else
            Insert_After_And_Analyze (Node, Check_Node);
         end if;
      end loop;
   end Insert_Range_Checks;

   ------------------------
   -- Insert_Valid_Check --
   ------------------------

   procedure Insert_Valid_Check
     (Expr          : Node_Id;
      Related_Id    : Entity_Id := Empty;
      Is_Low_Bound  : Boolean   := False;
      Is_High_Bound : Boolean   := False)
   is
      Loc : constant Source_Ptr := Sloc (Expr);
      Typ : constant Entity_Id  := Etype (Expr);
      Exp : Node_Id;

   begin
      --  Do not insert if checks off, or if not checking validity or if
      --  expression is known to be valid.

      if not Validity_Checks_On
        or else Range_Or_Validity_Checks_Suppressed (Expr)
        or else Expr_Known_Valid (Expr)
      then
         return;

      --  Do not insert checks within a predicate function. This will arise
      --  if the current unit and the predicate function are being compiled
      --  with validity checks enabled.

      elsif Present (Predicate_Function (Typ))
        and then Current_Scope = Predicate_Function (Typ)
      then
         return;

      --  If the expression is a packed component of a modular type of the
      --  right size, the data is always valid.

      elsif Nkind (Expr) = N_Selected_Component
        and then Present (Component_Clause (Entity (Selector_Name (Expr))))
        and then Is_Modular_Integer_Type (Typ)
        and then Modulus (Typ) = 2 ** Esize (Entity (Selector_Name (Expr)))
      then
         return;

      --  Do not generate a validity check when inside a generic unit as this
      --  is an expansion activity.

      elsif Inside_A_Generic then
         return;
      end if;

      --  Entities declared in Lock_free protected types must be treated as
      --  volatile, and we must inhibit validity checks to prevent improper
      --  constant folding.

      if Is_Entity_Name (Expr)
        and then Is_Subprogram (Scope (Entity (Expr)))
        and then Present (Protected_Subprogram (Scope (Entity (Expr))))
        and then Uses_Lock_Free
                   (Scope (Protected_Subprogram (Scope (Entity (Expr)))))
      then
         return;
      end if;

      --  If we have a checked conversion, then validity check applies to
      --  the expression inside the conversion, not the result, since if
      --  the expression inside is valid, then so is the conversion result.

      Exp := Expr;
      while Nkind (Exp) = N_Type_Conversion loop
         Exp := Expression (Exp);
      end loop;

      --  Do not generate a check for a variable which already validates the
      --  value of an assignable object.

      if Is_Validation_Variable_Reference (Exp) then
         return;
      end if;

      declare
         CE     : Node_Id;
         PV     : Node_Id;
         Var_Id : Entity_Id;

      begin
         --  If the expression denotes an assignable object, capture its value
         --  in a variable and replace the original expression by the variable.
         --  This approach has several effects:

         --    1) The evaluation of the object results in only one read in the
         --       case where the object is atomic or volatile.

         --         Var ... := Object;  --  read

         --    2) The captured value is the one verified by attribute 'Valid.
         --       As a result the object is not evaluated again, which would
         --       result in an unwanted read in the case where the object is
         --       atomic or volatile.

         --         if not Var'Valid then     --  OK, no read of Object

         --         if not Object'Valid then  --  Wrong, extra read of Object

         --    3) The captured value replaces the original object reference.
         --       As a result the object is not evaluated again, in the same
         --       vein as 2).

         --         ... Var ...     --  OK, no read of Object

         --         ... Object ...  --  Wrong, extra read of Object

         --    4) The use of a variable to capture the value of the object
         --       allows the propagation of any changes back to the original
         --       object.

         --         procedure Call (Val : in out ...);

         --         Var : ... := Object;   --  read Object
         --         if not Var'Valid then  --  validity check
         --         Call (Var);            --  modify Var
         --         Object := Var;         --  update Object

         if Is_Variable (Exp) then
            Var_Id := Make_Temporary (Loc, 'T', Exp);

            --  Because we could be dealing with a transient scope which would
            --  cause our object declaration to remain unanalyzed we must do
            --  some manual decoration.

            Mutate_Ekind (Var_Id, E_Variable);
            Set_Etype (Var_Id, Typ);

            Insert_Action (Exp,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Var_Id,
                Object_Definition   => New_Occurrence_Of (Typ, Loc),
                Expression          => New_Copy_Tree (Exp)),
              Suppress => Validity_Check);

            Set_Validated_Object (Var_Id, New_Copy_Tree (Exp));

            Rewrite (Exp, New_Occurrence_Of (Var_Id, Loc));

            --  Move the Do_Range_Check flag over to the new Exp so it doesn't
            --  get lost and doesn't leak elsewhere.

            if Do_Range_Check (Validated_Object (Var_Id)) then
               Set_Do_Range_Check (Exp);
               Set_Do_Range_Check (Validated_Object (Var_Id), False);
            end if;

            PV := New_Occurrence_Of (Var_Id, Loc);

         --  Otherwise the expression does not denote a variable. Force its
         --  evaluation by capturing its value in a constant. Generate:

         --    Temp : constant ... := Exp;

         else
            Force_Evaluation
              (Exp           => Exp,
               Related_Id    => Related_Id,
               Is_Low_Bound  => Is_Low_Bound,
               Is_High_Bound => Is_High_Bound);

            PV := New_Copy_Tree (Exp);
         end if;

         --  A rather specialized test. If PV is an analyzed expression which
         --  is an indexed component of a packed array that has not been
         --  properly expanded, turn off its Analyzed flag to make sure it
         --  gets properly reexpanded. If the prefix is an access value,
         --  the dereference will be added later.

         --  The reason this arises is that Duplicate_Subexpr_No_Checks did
         --  an analyze with the old parent pointer. This may point e.g. to
         --  a subprogram call, which deactivates this expansion.

         if Analyzed (PV)
           and then Nkind (PV) = N_Indexed_Component
           and then Is_Array_Type (Etype (Prefix (PV)))
           and then Present (Packed_Array_Impl_Type (Etype (Prefix (PV))))
         then
            Set_Analyzed (PV, False);
         end if;

         --  Build the raise CE node to check for validity. We build a type
         --  qualification for the prefix, since it may not be of the form of
         --  a name, and we don't care in this context!

         CE :=
           Make_Raise_Constraint_Error (Loc,
             Condition =>
               Make_Op_Not (Loc,
                 Right_Opnd =>
                   Make_Attribute_Reference (Loc,
                     Prefix         => PV,
                     Attribute_Name => Name_Valid)),
             Reason    => CE_Invalid_Data);

         --  Insert the validity check. Note that we do this with validity
         --  checks turned off, to avoid recursion, we do not want validity
         --  checks on the validity checking code itself.

         Insert_Action (Expr, CE, Suppress => Validity_Check);

         --  If the expression is a reference to an element of a bit-packed
         --  array, then it is rewritten as a renaming declaration. If the
         --  expression is an actual in a call, it has not been expanded,
         --  waiting for the proper point at which to do it. The same happens
         --  with renamings, so that we have to force the expansion now. This
         --  non-local complication is due to code in exp_ch2,adb, exp_ch4.adb
         --  and exp_ch6.adb.

         if Is_Entity_Name (Exp)
           and then Nkind (Parent (Entity (Exp))) =
                                                 N_Object_Renaming_Declaration
         then
            declare
               Old_Exp : constant Node_Id := Name (Parent (Entity (Exp)));
            begin
               if Nkind (Old_Exp) = N_Indexed_Component
                 and then Is_Bit_Packed_Array (Etype (Prefix (Old_Exp)))
               then
                  Expand_Packed_Element_Reference (Old_Exp);
               end if;
            end;
         end if;
      end;
   end Insert_Valid_Check;

   -------------------------------------
   -- Is_Signed_Integer_Arithmetic_Op --
   -------------------------------------

   function Is_Signed_Integer_Arithmetic_Op (N : Node_Id) return Boolean is
   begin
      case Nkind (N) is
         when N_Op_Abs
            | N_Op_Add
            | N_Op_Divide
            | N_Op_Expon
            | N_Op_Minus
            | N_Op_Mod
            | N_Op_Multiply
            | N_Op_Plus
            | N_Op_Rem
            | N_Op_Subtract
         =>
            return Is_Signed_Integer_Type (Etype (N));

         when N_Case_Expression
            | N_If_Expression
         =>
            return Is_Signed_Integer_Type (Etype (N));

         when others =>
            return False;
      end case;
   end Is_Signed_Integer_Arithmetic_Op;

   ----------------------------------
   -- Install_Null_Excluding_Check --
   ----------------------------------

   procedure Install_Null_Excluding_Check (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (Parent (N));
      Typ : constant Entity_Id  := Etype (N);

      function Safe_To_Capture_In_Parameter_Value return Boolean;
      --  Determines if it is safe to capture Known_Non_Null status for an
      --  the entity referenced by node N. The caller ensures that N is indeed
      --  an entity name. It is safe to capture the non-null status for an IN
      --  parameter when the reference occurs within a declaration that is sure
      --  to be executed as part of the declarative region.

      procedure Mark_Non_Null;
      --  After installation of check, if the node in question is an entity
      --  name, then mark this entity as non-null if possible.

      function Safe_To_Capture_In_Parameter_Value return Boolean is
         E     : constant Entity_Id := Entity (N);
         S     : constant Entity_Id := Current_Scope;
         S_Par : Node_Id;

      begin
         if Ekind (E) /= E_In_Parameter then
            return False;
         end if;

         --  Two initial context checks. We must be inside a subprogram body
         --  with declarations and reference must not appear in nested scopes.

         if (Ekind (S) /= E_Function and then Ekind (S) /= E_Procedure)
           or else Scope (E) /= S
         then
            return False;
         end if;

         S_Par := Parent (Parent (S));

         if Nkind (S_Par) /= N_Subprogram_Body
           or else No (Declarations (S_Par))
         then
            return False;
         end if;

         declare
            N_Decl : Node_Id;
            P      : Node_Id;

         begin
            --  Retrieve the declaration node of N (if any). Note that N
            --  may be a part of a complex initialization expression.

            P := Parent (N);
            N_Decl := Empty;
            while Present (P) loop

               --  If we have a short circuit form, and we are within the right
               --  hand expression, we return false, since the right hand side
               --  is not guaranteed to be elaborated.

               if Nkind (P) in N_Short_Circuit
                 and then N = Right_Opnd (P)
               then
                  return False;
               end if;

               --  Similarly, if we are in an if expression and not part of the
               --  condition, then we return False, since neither the THEN or
               --  ELSE dependent expressions will always be elaborated.

               if Nkind (P) = N_If_Expression
                 and then N /= First (Expressions (P))
               then
                  return False;
               end if;

               --  If within a case expression, and not part of the expression,
               --  then return False, since a particular dependent expression
               --  may not always be elaborated

               if Nkind (P) = N_Case_Expression
                 and then N /= Expression (P)
               then
                  return False;
               end if;

               --  While traversing the parent chain, if node N belongs to a
               --  statement, then it may never appear in a declarative region.

               if Nkind (P) in N_Statement_Other_Than_Procedure_Call
                 or else Nkind (P) = N_Procedure_Call_Statement
               then
                  return False;
               end if;

               --  If we are at a declaration, record it and exit

               if Nkind (P) in N_Declaration
                 and then Nkind (P) not in N_Subprogram_Specification
               then
                  N_Decl := P;
                  exit;
               end if;

               P := Parent (P);
            end loop;

            if No (N_Decl) then
               return False;
            end if;

            return List_Containing (N_Decl) = Declarations (S_Par);
         end;
      end Safe_To_Capture_In_Parameter_Value;

      -------------------
      -- Mark_Non_Null --
      -------------------

      procedure Mark_Non_Null is
      begin
         --  Only case of interest is if node N is an entity name

         if Is_Entity_Name (N) then

            --  For sure, we want to clear an indication that this is known to
            --  be null, since if we get past this check, it definitely is not.

            Set_Is_Known_Null (Entity (N), False);

            --  We can mark the entity as known to be non-null if either it is
            --  safe to capture the value, or in the case of an IN parameter,
            --  which is a constant, if the check we just installed is in the
            --  declarative region of the subprogram body. In this latter case,
            --  a check is decisive for the rest of the body if the expression
            --  is sure to be elaborated, since we know we have to elaborate
            --  all declarations before executing the body.

            --  Couldn't this always be part of Safe_To_Capture_Value ???

            if Safe_To_Capture_Value (N, Entity (N))
              or else Safe_To_Capture_In_Parameter_Value
            then
               Set_Is_Known_Non_Null (Entity (N));
            end if;
         end if;
      end Mark_Non_Null;

   --  Start of processing for Install_Null_Excluding_Check

   begin
      --  No need to add null-excluding checks when the tree may not be fully
      --  decorated.

      if Serious_Errors_Detected > 0 then
         return;
      end if;

      pragma Assert (Is_Access_Type (Typ));

      --  No check inside a generic, check will be emitted in instance

      if Inside_A_Generic then
         return;
      end if;

      --  No check needed if known to be non-null

      if Known_Non_Null (N) then
         return;
      end if;

      --  If known to be null, here is where we generate a compile time check

      if Known_Null (N) then

         --  Avoid generating warning message inside init procs. In SPARK mode
         --  we can go ahead and call Apply_Compile_Time_Constraint_Error
         --  since it will be turned into an error in any case.

         if (not Inside_Init_Proc or else SPARK_Mode = On)

           --  Do not emit the warning within a conditional expression,
           --  where the expression might not be evaluated, and the warning
           --  appear as extraneous noise.

           and then not Within_Case_Or_If_Expression (N)
         then
            Apply_Compile_Time_Constraint_Error
              (N, "null value not allowed here??", CE_Access_Check_Failed);

         --  Remaining cases, where we silently insert the raise

         else
            Insert_Action (N,
              Make_Raise_Constraint_Error (Loc,
                Reason => CE_Access_Check_Failed));
         end if;

         Mark_Non_Null;
         return;
      end if;

      --  If entity is never assigned, for sure a warning is appropriate

      if Is_Entity_Name (N) then
         Check_Unset_Reference (N);
      end if;

      --  No check needed if checks are suppressed on the range. Note that we
      --  don't set Is_Known_Non_Null in this case (we could legitimately do
      --  so, since the program is erroneous, but we don't like to casually
      --  propagate such conclusions from erroneosity).

      if Access_Checks_Suppressed (Typ) then
         return;
      end if;

      --  No check needed for access to concurrent record types generated by
      --  the expander. This is not just an optimization (though it does indeed
      --  remove junk checks). It also avoids generation of junk warnings.

      if Nkind (N) in N_Has_Chars
        and then Chars (N) = Name_uObject
        and then Is_Concurrent_Record_Type
                   (Directly_Designated_Type (Etype (N)))
      then
         return;
      end if;

      --  No check needed in interface thunks since the runtime check is
      --  already performed at the caller side.

      if Is_Thunk (Current_Scope) then
         return;
      end if;

      --  In GNATprove mode, we do not apply the check

      if GNATprove_Mode then
         return;
      end if;

      --  Otherwise install access check

      Insert_Action (N,
        Make_Raise_Constraint_Error (Loc,
          Condition =>
            Make_Op_Eq (Loc,
              Left_Opnd  => Duplicate_Subexpr_Move_Checks (N),
              Right_Opnd => Make_Null (Loc)),
          Reason => CE_Access_Check_Failed));

      Mark_Non_Null;
   end Install_Null_Excluding_Check;

   -----------------------------------------
   -- Install_Primitive_Elaboration_Check --
   -----------------------------------------

   procedure Install_Primitive_Elaboration_Check (Subp_Body : Node_Id) is
      function Within_Compilation_Unit_Instance
        (Subp_Id : Entity_Id) return Boolean;
      --  Determine whether subprogram Subp_Id appears within an instance which
      --  acts as a compilation unit.

      --------------------------------------
      -- Within_Compilation_Unit_Instance --
      --------------------------------------

      function Within_Compilation_Unit_Instance
        (Subp_Id : Entity_Id) return Boolean
      is
         Pack : Entity_Id;

      begin
         --  Examine the scope chain looking for a compilation-unit-level
         --  instance.

         Pack := Scope (Subp_Id);
         while Present (Pack) and then Pack /= Standard_Standard loop
            if Ekind (Pack) = E_Package
              and then Is_Generic_Instance (Pack)
              and then Nkind (Parent (Unit_Declaration_Node (Pack))) =
                         N_Compilation_Unit
            then
               return True;
            end if;

            Pack := Scope (Pack);
         end loop;

         return False;
      end Within_Compilation_Unit_Instance;

      --  Local declarations

      Context   : constant Node_Id    := Parent (Subp_Body);
      Loc       : constant Source_Ptr := Sloc (Subp_Body);
      Subp_Id   : constant Entity_Id  := Unique_Defining_Entity (Subp_Body);
      Subp_Decl : constant Node_Id    := Unit_Declaration_Node (Subp_Id);

      Decls    : List_Id;
      Flag_Id  : Entity_Id;
      Set_Ins  : Node_Id;
      Set_Stmt : Node_Id;
      Tag_Typ  : Entity_Id;

   --  Start of processing for Install_Primitive_Elaboration_Check

   begin
      --  Do not generate an elaboration check in compilation modes where
      --  expansion is not desirable.

      if GNATprove_Mode then
         return;

      --  Do not generate an elaboration check if all checks have been
      --  suppressed.

      elsif Suppress_Checks then
         return;

      --  Do not generate an elaboration check if the related subprogram is
      --  not subject to elaboration checks.

      elsif Elaboration_Checks_Suppressed (Subp_Id) then
         return;

      --  Do not generate an elaboration check if such code is not desirable

      elsif Restriction_Active (No_Elaboration_Code) then
         return;

      --  If pragma Pure or Preelaborate applies, then these elaboration checks
      --  cannot fail, so do not generate them.

      elsif In_Preelaborated_Unit then
         return;

      --  Do not generate an elaboration check if exceptions cannot be used,
      --  caught, or propagated.

      elsif not Exceptions_OK then
         return;

      --  Do not consider subprograms that are compilation units, because they
      --  cannot be the target of a dispatching call.

      elsif Nkind (Context) = N_Compilation_Unit then
         return;

      --  Do not consider anything other than nonabstract library-level source
      --  primitives.

      elsif not
        (Comes_From_Source (Subp_Id)
          and then Is_Library_Level_Entity (Subp_Id)
          and then Is_Primitive (Subp_Id)
          and then not Is_Abstract_Subprogram (Subp_Id))
      then
         return;

      --  Do not consider inlined primitives, because once the body is inlined
      --  the reference to the elaboration flag will be out of place and will
      --  result in an undefined symbol.

      elsif Is_Inlined (Subp_Id) or else Has_Pragma_Inline (Subp_Id) then
         return;

      --  Do not generate a duplicate elaboration check. This happens only in
      --  the case of primitives completed by an expression function, as the
      --  corresponding body is apparently analyzed and expanded twice.

      elsif Analyzed (Subp_Body) then
         return;

      --  Do not consider primitives that occur within an instance that is a
      --  compilation unit. Such an instance defines its spec and body out of
      --  order (body is first) within the tree, which causes the reference to
      --  the elaboration flag to appear as an undefined symbol.

      elsif Within_Compilation_Unit_Instance (Subp_Id) then
         return;
      end if;

      Tag_Typ := Find_Dispatching_Type (Subp_Id);

      --  Only tagged primitives may be the target of a dispatching call

      if No (Tag_Typ) then
         return;

      --  Do not consider finalization-related primitives, because they may
      --  need to be called while elaboration is taking place.

      elsif Is_Controlled (Tag_Typ)
        and then
          Chars (Subp_Id) in Name_Adjust | Name_Finalize | Name_Initialize
      then
         return;
      end if;

      --  Create the declaration of the elaboration flag. The name carries a
      --  unique counter in case of name overloading.

      Flag_Id :=
        Make_Defining_Identifier (Loc,
          Chars => New_External_Name (Chars (Subp_Id), 'E', -1));
      Set_Is_Frozen (Flag_Id);

      --  Insert the declaration of the elaboration flag in front of the
      --  primitive spec and analyze it in the proper context.

      Push_Scope (Scope (Subp_Id));

      --  Generate:
      --    E : Boolean := False;

      Insert_Action (Subp_Decl,
        Make_Object_Declaration (Loc,
          Defining_Identifier => Flag_Id,
          Object_Definition   => New_Occurrence_Of (Standard_Boolean, Loc),
          Expression          => New_Occurrence_Of (Standard_False, Loc)));
      Pop_Scope;

      --  Prevent the compiler from optimizing the elaboration check by killing
      --  the current value of the flag and the associated assignment.

      Set_Current_Value   (Flag_Id, Empty);
      Set_Last_Assignment (Flag_Id, Empty);

      --  Add a check at the top of the body declarations to ensure that the
      --  elaboration flag has been set.

      Decls := Declarations (Subp_Body);

      if No (Decls) then
         Decls := New_List;
         Set_Declarations (Subp_Body, Decls);
      end if;

      --  Generate:
      --    if not F then
      --       raise Program_Error with "access before elaboration";
      --    end if;

      Prepend_To (Decls,
        Make_Raise_Program_Error (Loc,
          Condition =>
            Make_Op_Not (Loc,
              Right_Opnd => New_Occurrence_Of (Flag_Id, Loc)),
          Reason    => PE_Access_Before_Elaboration));

      Analyze (First (Decls));

      --  Set the elaboration flag once the body has been elaborated. Insert
      --  the statement after the subprogram stub when the primitive body is
      --  a subunit.

      if Nkind (Context) = N_Subunit then
         Set_Ins := Corresponding_Stub (Context);
      else
         Set_Ins := Subp_Body;
      end if;

      --  Generate:
      --    E := True;

      Set_Stmt :=
        Make_Assignment_Statement (Loc,
          Name       => New_Occurrence_Of (Flag_Id, Loc),
          Expression => New_Occurrence_Of (Standard_True, Loc));

      --  Mark the assignment statement as elaboration code. This allows the
      --  early call region mechanism (see Sem_Elab) to properly ignore such
      --  assignments even though they are non-preelaborable code.

      Set_Is_Elaboration_Code (Set_Stmt);

      Insert_After_And_Analyze (Set_Ins, Set_Stmt);
   end Install_Primitive_Elaboration_Check;

   --------------------------
   -- Install_Static_Check --
   --------------------------

   procedure Install_Static_Check (R_Cno : Node_Id; Loc : Source_Ptr) is
      Stat : constant Boolean   := Is_OK_Static_Expression (R_Cno);
      Typ  : constant Entity_Id := Etype (R_Cno);

   begin
      Rewrite (R_Cno,
        Make_Raise_Constraint_Error (Loc,
          Reason => CE_Range_Check_Failed));
      Set_Analyzed (R_Cno);
      Set_Etype (R_Cno, Typ);
      Set_Raises_Constraint_Error (R_Cno);
      Set_Is_Static_Expression (R_Cno, Stat);

      --  Now deal with possible local raise handling

      Possible_Local_Raise (R_Cno, Standard_Constraint_Error);
   end Install_Static_Check;

   -------------------------
   -- Is_Check_Suppressed --
   -------------------------

   function Is_Check_Suppressed (E : Entity_Id; C : Check_Id) return Boolean is
      Ptr : Suppress_Stack_Entry_Ptr;

   begin
      --  First search the local entity suppress stack. We search this from the
      --  top of the stack down so that we get the innermost entry that applies
      --  to this case if there are nested entries.

      Ptr := Local_Suppress_Stack_Top;
      while Ptr /= null loop
         if (Ptr.Entity = Empty or else Ptr.Entity = E)
           and then (Ptr.Check = All_Checks or else Ptr.Check = C)
         then
            return Ptr.Suppress;
         end if;

         Ptr := Ptr.Prev;
      end loop;

      --  Now search the global entity suppress table for a matching entry.
      --  We also search this from the top down so that if there are multiple
      --  pragmas for the same entity, the last one applies (not clear what
      --  or whether the RM specifies this handling, but it seems reasonable).

      Ptr := Global_Suppress_Stack_Top;
      while Ptr /= null loop
         if (Ptr.Entity = Empty or else Ptr.Entity = E)
           and then (Ptr.Check = All_Checks or else Ptr.Check = C)
         then
            return Ptr.Suppress;
         end if;

         Ptr := Ptr.Prev;
      end loop;

      --  If we did not find a matching entry, then use the normal scope
      --  suppress value after all (actually this will be the global setting
      --  since it clearly was not overridden at any point). For a predefined
      --  check, we test the specific flag. For a user defined check, we check
      --  the All_Checks flag. The Overflow flag requires special handling to
      --  deal with the General vs Assertion case.

      if C = Overflow_Check then
         return Overflow_Checks_Suppressed (Empty);

      elsif C in Predefined_Check_Id then
         return Scope_Suppress.Suppress (C);

      else
         return Scope_Suppress.Suppress (All_Checks);
      end if;
   end Is_Check_Suppressed;

   ---------------------
   -- Kill_All_Checks --
   ---------------------

   procedure Kill_All_Checks is
   begin
      if Debug_Flag_CC then
         w ("Kill_All_Checks");
      end if;

      --  We reset the number of saved checks to zero, and also modify all
      --  stack entries for statement ranges to indicate that the number of
      --  checks at each level is now zero.

      Num_Saved_Checks := 0;

      --  Note: the Int'Min here avoids any possibility of J being out of
      --  range when called from e.g. Conditional_Statements_Begin.

      for J in 1 .. Int'Min (Saved_Checks_TOS, Saved_Checks_Stack'Last) loop
         Saved_Checks_Stack (J) := 0;
      end loop;
   end Kill_All_Checks;

   -----------------
   -- Kill_Checks --
   -----------------

   procedure Kill_Checks (V : Entity_Id) is
   begin
      if Debug_Flag_CC then
         w ("Kill_Checks for entity", Int (V));
      end if;

      for J in 1 .. Num_Saved_Checks loop
         if Saved_Checks (J).Entity = V then
            if Debug_Flag_CC then
               w ("   Checks killed for saved check ", J);
            end if;

            Saved_Checks (J).Killed := True;
         end if;
      end loop;
   end Kill_Checks;

   ------------------------------
   -- Length_Checks_Suppressed --
   ------------------------------

   function Length_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E) and then Checks_May_Be_Suppressed (E) then
         return Is_Check_Suppressed (E, Length_Check);
      else
         return Scope_Suppress.Suppress (Length_Check);
      end if;
   end Length_Checks_Suppressed;

   -----------------------
   -- Make_Bignum_Block --
   -----------------------

   function Make_Bignum_Block (Loc : Source_Ptr) return Node_Id is
      M : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uM);
   begin
      return
        Make_Block_Statement (Loc,
          Declarations               =>
            New_List (Build_SS_Mark_Call (Loc, M)),
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => New_List (Build_SS_Release_Call (Loc, M))));
   end Make_Bignum_Block;

   ----------------------------------
   -- Minimize_Eliminate_Overflows --
   ----------------------------------

   --  This is a recursive routine that is called at the top of an expression
   --  tree to properly process overflow checking for a whole subtree by making
   --  recursive calls to process operands. This processing may involve the use
   --  of bignum or long long integer arithmetic, which will change the types
   --  of operands and results. That's why we can't do this bottom up (since
   --  it would interfere with semantic analysis).

   --  What happens is that if MINIMIZED/ELIMINATED mode is in effect then
   --  the operator expansion routines, as well as the expansion routines for
   --  if/case expression, do nothing (for the moment) except call the routine
   --  to apply the overflow check (Apply_Arithmetic_Overflow_Check). That
   --  routine does nothing for non top-level nodes, so at the point where the
   --  call is made for the top level node, the entire expression subtree has
   --  not been expanded, or processed for overflow. All that has to happen as
   --  a result of the top level call to this routine.

   --  As noted above, the overflow processing works by making recursive calls
   --  for the operands, and figuring out what to do, based on the processing
   --  of these operands (e.g. if a bignum operand appears, the parent op has
   --  to be done in bignum mode), and the determined ranges of the operands.

   --  After possible rewriting of a constituent subexpression node, a call is
   --  made to either reexpand the node (if nothing has changed) or reanalyze
   --  the node (if it has been modified by the overflow check processing). The
   --  Analyzed_Flag is set to False before the reexpand/reanalyze. To avoid
   --  a recursive call into the whole overflow apparatus, an important rule
   --  for this call is that the overflow handling mode must be temporarily set
   --  to STRICT.

   procedure Minimize_Eliminate_Overflows
     (N         : Node_Id;
      Lo        : out Uint;
      Hi        : out Uint;
      Top_Level : Boolean)
   is
      Rtyp : constant Entity_Id := Etype (N);
      pragma Assert (Is_Signed_Integer_Type (Rtyp));
      --  Result type, must be a signed integer type

      Check_Mode : constant Overflow_Mode_Type := Overflow_Check_Mode;
      pragma Assert (Check_Mode in Minimized_Or_Eliminated);

      Loc : constant Source_Ptr := Sloc (N);

      Rlo, Rhi : Uint;
      --  Ranges of values for right operand (operator case)

      Llo : Uint := No_Uint;  -- initialize to prevent warning
      Lhi : Uint := No_Uint;  -- initialize to prevent warning
      --  Ranges of values for left operand (operator case)

      LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
      --  Operands and results are of this type when we convert

      LLLo : constant Uint := Intval (Type_Low_Bound  (LLIB));
      LLHi : constant Uint := Intval (Type_High_Bound (LLIB));
      --  Bounds of Long_Long_Integer

      Binary : constant Boolean := Nkind (N) in N_Binary_Op;
      --  Indicates binary operator case

      OK : Boolean;
      --  Used in call to Determine_Range

      Bignum_Operands : Boolean;
      --  Set True if one or more operands is already of type Bignum, meaning
      --  that for sure (regardless of Top_Level setting) we are committed to
      --  doing the operation in Bignum mode (or in the case of a case or if
      --  expression, converting all the dependent expressions to Bignum).

      Long_Long_Integer_Operands : Boolean;
      --  Set True if one or more operands is already of type Long_Long_Integer
      --  which means that if the result is known to be in the result type
      --  range, then we must convert such operands back to the result type.

      procedure Reanalyze (Typ : Entity_Id; Suppress : Boolean := False);
      --  This is called when we have modified the node and we therefore need
      --  to reanalyze it. It is important that we reset the mode to STRICT for
      --  this reanalysis, since if we leave it in MINIMIZED or ELIMINATED mode
      --  we would reenter this routine recursively which would not be good.
      --  The argument Suppress is set True if we also want to suppress
      --  overflow checking for the reexpansion (this is set when we know
      --  overflow is not possible). Typ is the type for the reanalysis.

      procedure Reexpand (Suppress : Boolean := False);
      --  This is like Reanalyze, but does not do the Analyze step, it only
      --  does a reexpansion. We do this reexpansion in STRICT mode, so that
      --  instead of reentering the MINIMIZED/ELIMINATED mode processing, we
      --  follow the normal expansion path (e.g. converting A**4 to A**2**2).
      --  Note that skipping reanalysis is not just an optimization, testing
      --  has showed up several complex cases in which reanalyzing an already
      --  analyzed node causes incorrect behavior.

      function In_Result_Range return Boolean;
      --  Returns True iff Lo .. Hi are within range of the result type

      procedure Max (A : in out Uint; B : Uint);
      --  If A is No_Uint, sets A to B, else to UI_Max (A, B)

      procedure Min (A : in out Uint; B : Uint);
      --  If A is No_Uint, sets A to B, else to UI_Min (A, B)

      ---------------------
      -- In_Result_Range --
      ---------------------

      function In_Result_Range return Boolean is
      begin
         if No (Lo) or else No (Hi) then
            return False;

         elsif Is_OK_Static_Subtype (Etype (N)) then
            return Lo >= Expr_Value (Type_Low_Bound  (Rtyp))
                     and then
                   Hi <= Expr_Value (Type_High_Bound (Rtyp));

         else
            return Lo >= Expr_Value (Type_Low_Bound  (Base_Type (Rtyp)))
                     and then
                   Hi <= Expr_Value (Type_High_Bound (Base_Type (Rtyp)));
         end if;
      end In_Result_Range;

      ---------
      -- Max --
      ---------

      procedure Max (A : in out Uint; B : Uint) is
      begin
         if No (A) or else B > A then
            A := B;
         end if;
      end Max;

      ---------
      -- Min --
      ---------

      procedure Min (A : in out Uint; B : Uint) is
      begin
         if No (A) or else B < A then
            A := B;
         end if;
      end Min;

      ---------------
      -- Reanalyze --
      ---------------

      procedure Reanalyze (Typ : Entity_Id; Suppress : Boolean := False) is
         Svg : constant Overflow_Mode_Type :=
                 Scope_Suppress.Overflow_Mode_General;
         Sva : constant Overflow_Mode_Type :=
                 Scope_Suppress.Overflow_Mode_Assertions;
         Svo : constant Boolean             :=
                 Scope_Suppress.Suppress (Overflow_Check);

      begin
         Scope_Suppress.Overflow_Mode_General    := Strict;
         Scope_Suppress.Overflow_Mode_Assertions := Strict;

         if Suppress then
            Scope_Suppress.Suppress (Overflow_Check) := True;
         end if;

         Analyze_And_Resolve (N, Typ);

         Scope_Suppress.Suppress (Overflow_Check) := Svo;
         Scope_Suppress.Overflow_Mode_General     := Svg;
         Scope_Suppress.Overflow_Mode_Assertions  := Sva;
      end Reanalyze;

      --------------
      -- Reexpand --
      --------------

      procedure Reexpand (Suppress : Boolean := False) is
         Svg : constant Overflow_Mode_Type :=
                 Scope_Suppress.Overflow_Mode_General;
         Sva : constant Overflow_Mode_Type :=
                 Scope_Suppress.Overflow_Mode_Assertions;
         Svo : constant Boolean             :=
                 Scope_Suppress.Suppress (Overflow_Check);

      begin
         Scope_Suppress.Overflow_Mode_General    := Strict;
         Scope_Suppress.Overflow_Mode_Assertions := Strict;
         Set_Analyzed (N, False);

         if Suppress then
            Scope_Suppress.Suppress (Overflow_Check) := True;
         end if;

         Expand (N);

         Scope_Suppress.Suppress (Overflow_Check) := Svo;
         Scope_Suppress.Overflow_Mode_General     := Svg;
         Scope_Suppress.Overflow_Mode_Assertions  := Sva;
      end Reexpand;

   --  Start of processing for Minimize_Eliminate_Overflows

   begin
      --  Default initialize Lo and Hi since these are not guaranteed to be
      --  set otherwise.

      Lo := No_Uint;
      Hi := No_Uint;

      --  Case where we do not have a signed integer arithmetic operation

      if not Is_Signed_Integer_Arithmetic_Op (N) then

         --  Use the normal Determine_Range routine to get the range. We
         --  don't require operands to be valid, invalid values may result in
         --  rubbish results where the result has not been properly checked for
         --  overflow, that's fine.

         Determine_Range (N, OK, Lo, Hi, Assume_Valid => False);

         --  If Determine_Range did not work (can this in fact happen? Not
         --  clear but might as well protect), use type bounds.

         if not OK then
            Lo := Intval (Type_Low_Bound  (Base_Type (Etype (N))));
            Hi := Intval (Type_High_Bound (Base_Type (Etype (N))));
         end if;

         --  If we don't have a binary operator, all we have to do is to set
         --  the Hi/Lo range, so we are done.

         return;

      --  Processing for if expression

      elsif Nkind (N) = N_If_Expression then
         declare
            Then_DE : constant Node_Id := Next (First (Expressions (N)));
            Else_DE : constant Node_Id := Next (Then_DE);

         begin
            Bignum_Operands := False;

            Minimize_Eliminate_Overflows
              (Then_DE, Lo, Hi, Top_Level => False);

            if No (Lo) then
               Bignum_Operands := True;
            end if;

            Minimize_Eliminate_Overflows
              (Else_DE, Rlo, Rhi, Top_Level => False);

            if No (Rlo) then
               Bignum_Operands := True;
            else
               Long_Long_Integer_Operands :=
                 Etype (Then_DE) = LLIB or else Etype (Else_DE) = LLIB;

               Min (Lo, Rlo);
               Max (Hi, Rhi);
            end if;

            --  If at least one of our operands is now Bignum, we must rebuild
            --  the if expression to use Bignum operands. We will analyze the
            --  rebuilt if expression with overflow checks off, since once we
            --  are in bignum mode, we are all done with overflow checks.

            if Bignum_Operands then
               Rewrite (N,
                 Make_If_Expression (Loc,
                   Expressions => New_List (
                     Remove_Head (Expressions (N)),
                     Convert_To_Bignum (Then_DE),
                     Convert_To_Bignum (Else_DE)),
                   Is_Elsif    => Is_Elsif (N)));

               Reanalyze (RTE (RE_Bignum), Suppress => True);

            --  If we have no Long_Long_Integer operands, then we are in result
            --  range, since it means that none of our operands felt the need
            --  to worry about overflow (otherwise it would have already been
            --  converted to long long integer or bignum). We reexpand to
            --  complete the expansion of the if expression (but we do not
            --  need to reanalyze).

            elsif not Long_Long_Integer_Operands then
               Set_Do_Overflow_Check (N, False);
               Reexpand;

            --  Otherwise convert us to long long integer mode. Note that we
            --  don't need any further overflow checking at this level.

            else
               Convert_To_And_Rewrite (LLIB, Then_DE);
               Convert_To_And_Rewrite (LLIB, Else_DE);
               Set_Etype (N, LLIB);

               --  Now reanalyze with overflow checks off

               Set_Do_Overflow_Check (N, False);
               Reanalyze (LLIB, Suppress => True);
            end if;
         end;

         return;

      --  Here for case expression

      elsif Nkind (N) = N_Case_Expression then
         Bignum_Operands := False;
         Long_Long_Integer_Operands := False;

         declare
            Alt : Node_Id;

         begin
            --  Loop through expressions applying recursive call

            Alt := First (Alternatives (N));
            while Present (Alt) loop
               declare
                  Aexp : constant Node_Id := Expression (Alt);

               begin
                  Minimize_Eliminate_Overflows
                    (Aexp, Lo, Hi, Top_Level => False);

                  if No (Lo) then
                     Bignum_Operands := True;
                  elsif Etype (Aexp) = LLIB then
                     Long_Long_Integer_Operands := True;
                  end if;
               end;

               Next (Alt);
            end loop;

            --  If we have no bignum or long long integer operands, it means
            --  that none of our dependent expressions could raise overflow.
            --  In this case, we simply return with no changes except for
            --  resetting the overflow flag, since we are done with overflow
            --  checks for this node. We will reexpand to get the needed
            --  expansion for the case expression, but we do not need to
            --  reanalyze, since nothing has changed.

            if not (Bignum_Operands or Long_Long_Integer_Operands) then
               Set_Do_Overflow_Check (N, False);
               Reexpand (Suppress => True);

            --  Otherwise we are going to rebuild the case expression using
            --  either bignum or long long integer operands throughout.

            else
               declare
                  Rtype    : Entity_Id := Empty;
                  New_Alts : List_Id;
                  New_Exp  : Node_Id;

               begin
                  New_Alts := New_List;
                  Alt := First (Alternatives (N));
                  while Present (Alt) loop
                     if Bignum_Operands then
                        New_Exp := Convert_To_Bignum (Expression (Alt));
                        Rtype   := RTE (RE_Bignum);
                     else
                        New_Exp := Convert_To (LLIB, Expression (Alt));
                        Rtype   := LLIB;
                     end if;

                     Append_To (New_Alts,
                       Make_Case_Expression_Alternative (Sloc (Alt),
                         Discrete_Choices => Discrete_Choices (Alt),
                         Expression       => New_Exp));

                     Next (Alt);
                  end loop;

                  Rewrite (N,
                    Make_Case_Expression (Loc,
                      Expression   => Expression (N),
                      Alternatives => New_Alts));

                  pragma Assert (Present (Rtype));
                  Reanalyze (Rtype, Suppress => True);
               end;
            end if;
         end;

         return;
      end if;

      --  If we have an arithmetic operator we make recursive calls on the
      --  operands to get the ranges (and to properly process the subtree
      --  that lies below us).

      Minimize_Eliminate_Overflows
        (Right_Opnd (N), Rlo, Rhi, Top_Level => False);

      if Binary then
         Minimize_Eliminate_Overflows
           (Left_Opnd (N), Llo, Lhi, Top_Level => False);
      end if;

      --  Record if we have Long_Long_Integer operands

      Long_Long_Integer_Operands :=
        Etype (Right_Opnd (N)) = LLIB
          or else (Binary and then Etype (Left_Opnd (N)) = LLIB);

      --  If either operand is a bignum, then result will be a bignum and we
      --  don't need to do any range analysis. As previously discussed we could
      --  do range analysis in such cases, but it could mean working with giant
      --  numbers at compile time for very little gain (the number of cases
      --  in which we could slip back from bignum mode is small).

      if No (Rlo) or else (Binary and then No (Llo)) then
         Lo := No_Uint;
         Hi := No_Uint;
         Bignum_Operands := True;

      --  Otherwise compute result range

      else
         Compute_Range_For_Arithmetic_Op
           (Nkind (N), Llo, Lhi, Rlo, Rhi, OK, Lo, Hi);
         Bignum_Operands := False;
      end if;

      --  Here for the case where we have not rewritten anything (no bignum
      --  operands or long long integer operands), and we know the result.
      --  If we know we are in the result range, and we do not have Bignum
      --  operands or Long_Long_Integer operands, we can just reexpand with
      --  overflow checks turned off (since we know we cannot have overflow).
      --  As always the reexpansion is required to complete expansion of the
      --  operator, but we do not need to reanalyze, and we prevent recursion
      --  by suppressing the check.

      if not (Bignum_Operands or Long_Long_Integer_Operands)
        and then In_Result_Range
      then
         Set_Do_Overflow_Check (N, False);
         Reexpand (Suppress => True);
         return;

      --  Here we know that we are not in the result range, and in the general
      --  case we will move into either the Bignum or Long_Long_Integer domain
      --  to compute the result. However, there is one exception. If we are
      --  at the top level, and we do not have Bignum or Long_Long_Integer
      --  operands, we will have to immediately convert the result back to
      --  the result type, so there is no point in Bignum/Long_Long_Integer
      --  fiddling.

      elsif Top_Level
        and then not (Bignum_Operands or Long_Long_Integer_Operands)

        --  One further refinement. If we are at the top level, but our parent
        --  is a type conversion, then go into bignum or long long integer node
        --  since the result will be converted to that type directly without
        --  going through the result type, and we may avoid an overflow. This
        --  is the case for example of Long_Long_Integer (A ** 4), where A is
        --  of type Integer, and the result A ** 4 fits in Long_Long_Integer
        --  but does not fit in Integer.

        and then Nkind (Parent (N)) /= N_Type_Conversion
      then
         --  Here keep original types, but we need to complete analysis

         --  One subtlety. We can't just go ahead and do an analyze operation
         --  here because it will cause recursion into the whole MINIMIZED/
         --  ELIMINATED overflow processing which is not what we want. Here
         --  we are at the top level, and we need a check against the result
         --  mode (i.e. we want to use STRICT mode). So do exactly that.
         --  Also, we have not modified the node, so this is a case where
         --  we need to reexpand, but not reanalyze.

         Reexpand;
         return;

      --  Cases where we do the operation in Bignum mode. This happens either
      --  because one of our operands is in Bignum mode already, or because
      --  the computed bounds are outside the bounds of Long_Long_Integer,
      --  which in some cases can be indicated by Hi and Lo being No_Uint.

      --  Note: we could do better here and in some cases switch back from
      --  Bignum mode to normal mode, e.g. big mod 2 must be in the range
      --  0 .. 1, but the cases are rare and it is not worth the effort.
      --  Failing to do this switching back is only an efficiency issue.

      elsif No (Lo) or else Lo < LLLo or else Hi > LLHi then

         --  OK, we are definitely outside the range of Long_Long_Integer. The
         --  question is whether to move to Bignum mode, or stay in the domain
         --  of Long_Long_Integer, signalling that an overflow check is needed.

         --  Obviously in MINIMIZED mode we stay with LLI, since we are not in
         --  the Bignum business. In ELIMINATED mode, we will normally move
         --  into Bignum mode, but there is an exception if neither of our
         --  operands is Bignum now, and we are at the top level (Top_Level
         --  set True). In this case, there is no point in moving into Bignum
         --  mode to prevent overflow if the caller will immediately convert
         --  the Bignum value back to LLI with an overflow check. It's more
         --  efficient to stay in LLI mode with an overflow check (if needed)

         if Check_Mode = Minimized
           or else (Top_Level and not Bignum_Operands)
         then
            if Do_Overflow_Check (N) then
               Enable_Overflow_Check (N);
            end if;

            --  The result now has to be in Long_Long_Integer mode, so adjust
            --  the possible range to reflect this. Note these calls also
            --  change No_Uint values from the top level case to LLI bounds.

            Max (Lo, LLLo);
            Min (Hi, LLHi);

         --  Otherwise we are in ELIMINATED mode and we switch to Bignum mode

         else
            pragma Assert (Check_Mode = Eliminated);

            declare
               Fent : Entity_Id;
               Args : List_Id;

            begin
               case Nkind (N) is
                  when N_Op_Abs =>
                     Fent := RTE (RE_Big_Abs);

                  when N_Op_Add =>
                     Fent := RTE (RE_Big_Add);

                  when N_Op_Divide =>
                     Fent := RTE (RE_Big_Div);

                  when N_Op_Expon =>
                     Fent := RTE (RE_Big_Exp);

                  when N_Op_Minus =>
                     Fent := RTE (RE_Big_Neg);

                  when N_Op_Mod =>
                     Fent := RTE (RE_Big_Mod);

                  when N_Op_Multiply =>
                     Fent := RTE (RE_Big_Mul);

                  when N_Op_Rem =>
                     Fent := RTE (RE_Big_Rem);

                  when N_Op_Subtract =>
                     Fent := RTE (RE_Big_Sub);

                  --  Anything else is an internal error, this includes the
                  --  N_Op_Plus case, since how can plus cause the result
                  --  to be out of range if the operand is in range?

                  when others =>
                     raise Program_Error;
               end case;

               --  Construct argument list for Bignum call, converting our
               --  operands to Bignum form if they are not already there.

               Args := New_List;

               if Binary then
                  Append_To (Args, Convert_To_Bignum (Left_Opnd (N)));
               end if;

               Append_To (Args, Convert_To_Bignum (Right_Opnd (N)));

               --  Now rewrite the arithmetic operator with a call to the
               --  corresponding bignum function.

               Rewrite (N,
                 Make_Function_Call (Loc,
                   Name                   => New_Occurrence_Of (Fent, Loc),
                   Parameter_Associations => Args));
               Reanalyze (RTE (RE_Bignum), Suppress => True);

               --  Indicate result is Bignum mode

               Lo := No_Uint;
               Hi := No_Uint;
               return;
            end;
         end if;

      --  Otherwise we are in range of Long_Long_Integer, so no overflow
      --  check is required, at least not yet.

      else
         Set_Do_Overflow_Check (N, False);
      end if;

      --  Here we are not in Bignum territory, but we may have long long
      --  integer operands that need special handling. First a special check:
      --  If an exponentiation operator exponent is of type Long_Long_Integer,
      --  it means we converted it to prevent overflow, but exponentiation
      --  requires a Natural right operand, so convert it back to Natural.
      --  This conversion may raise an exception which is fine.

      if Nkind (N) = N_Op_Expon and then Etype (Right_Opnd (N)) = LLIB then
         Convert_To_And_Rewrite (Standard_Natural, Right_Opnd (N));
      end if;

      --  Here we will do the operation in Long_Long_Integer. We do this even
      --  if we know an overflow check is required, better to do this in long
      --  long integer mode, since we are less likely to overflow.

      --  Convert right or only operand to Long_Long_Integer, except that
      --  we do not touch the exponentiation right operand.

      if Nkind (N) /= N_Op_Expon then
         Convert_To_And_Rewrite (LLIB, Right_Opnd (N));
      end if;

      --  Convert left operand to Long_Long_Integer for binary case

      if Binary then
         Convert_To_And_Rewrite (LLIB, Left_Opnd (N));
      end if;

      --  Reset node to unanalyzed

      Set_Analyzed (N, False);
      Set_Etype (N, Empty);
      Set_Entity (N, Empty);

      --  Now analyze this new node. This reanalysis will complete processing
      --  for the node. In particular we will complete the expansion of an
      --  exponentiation operator (e.g. changing A ** 2 to A * A), and also
      --  we will complete any division checks (since we have not changed the
      --  setting of the Do_Division_Check flag).

      --  We do this reanalysis in STRICT mode to avoid recursion into the
      --  MINIMIZED/ELIMINATED handling, since we are now done with that.

      declare
         SG : constant Overflow_Mode_Type :=
                Scope_Suppress.Overflow_Mode_General;
         SA : constant Overflow_Mode_Type :=
                Scope_Suppress.Overflow_Mode_Assertions;

      begin
         Scope_Suppress.Overflow_Mode_General    := Strict;
         Scope_Suppress.Overflow_Mode_Assertions := Strict;

         if not Do_Overflow_Check (N) then
            Reanalyze (LLIB, Suppress => True);
         else
            Reanalyze (LLIB);
         end if;

         Scope_Suppress.Overflow_Mode_General    := SG;
         Scope_Suppress.Overflow_Mode_Assertions := SA;
      end;
   end Minimize_Eliminate_Overflows;

   -------------------------
   -- Overflow_Check_Mode --
   -------------------------

   function Overflow_Check_Mode return Overflow_Mode_Type is
   begin
      if In_Assertion_Expr = 0 then
         return Scope_Suppress.Overflow_Mode_General;
      else
         return Scope_Suppress.Overflow_Mode_Assertions;
      end if;
   end Overflow_Check_Mode;

   --------------------------------
   -- Overflow_Checks_Suppressed --
   --------------------------------

   function Overflow_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E) and then Checks_May_Be_Suppressed (E) then
         return Is_Check_Suppressed (E, Overflow_Check);
      else
         return Scope_Suppress.Suppress (Overflow_Check);
      end if;
   end Overflow_Checks_Suppressed;

   ---------------------------------
   -- Predicate_Checks_Suppressed --
   ---------------------------------

   function Predicate_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E) and then Checks_May_Be_Suppressed (E) then
         return Is_Check_Suppressed (E, Predicate_Check);
      else
         return Scope_Suppress.Suppress (Predicate_Check);
      end if;
   end Predicate_Checks_Suppressed;

   -----------------------------
   -- Range_Checks_Suppressed --
   -----------------------------

   function Range_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E) then
         if Kill_Range_Checks (E) then
            return True;

         elsif Checks_May_Be_Suppressed (E) then
            return Is_Check_Suppressed (E, Range_Check);
         end if;
      end if;

      return Scope_Suppress.Suppress (Range_Check);
   end Range_Checks_Suppressed;

   -----------------------------------------
   -- Range_Or_Validity_Checks_Suppressed --
   -----------------------------------------

   --  Note: the coding would be simpler here if we simply made appropriate
   --  calls to Range/Validity_Checks_Suppressed, but that would result in
   --  duplicated checks which we prefer to avoid.

   function Range_Or_Validity_Checks_Suppressed
     (Expr : Node_Id) return Boolean
   is
   begin
      --  Immediate return if scope checks suppressed for either check

      if Scope_Suppress.Suppress (Range_Check)
           or
         Scope_Suppress.Suppress (Validity_Check)
      then
         return True;
      end if;

      --  If no expression, that's odd, decide that checks are suppressed,
      --  since we don't want anyone trying to do checks in this case, which
      --  is most likely the result of some other error.

      if No (Expr) then
         return True;
      end if;

      --  Expression is present, so perform suppress checks on type

      declare
         Typ : constant Entity_Id := Etype (Expr);
      begin
         if Checks_May_Be_Suppressed (Typ)
           and then (Is_Check_Suppressed (Typ, Range_Check)
                       or else
                     Is_Check_Suppressed (Typ, Validity_Check))
         then
            return True;
         end if;
      end;

      --  If expression is an entity name, perform checks on this entity

      if Is_Entity_Name (Expr) then
         declare
            Ent : constant Entity_Id := Entity (Expr);
         begin
            if Checks_May_Be_Suppressed (Ent) then
               return Is_Check_Suppressed (Ent, Range_Check)
                 or else Is_Check_Suppressed (Ent, Validity_Check);
            end if;
         end;
      end if;

      --  If we fall through, no checks suppressed

      return False;
   end Range_Or_Validity_Checks_Suppressed;

   -------------------
   -- Remove_Checks --
   -------------------

   procedure Remove_Checks (Expr : Node_Id) is
      function Process (N : Node_Id) return Traverse_Result;
      --  Process a single node during the traversal

      procedure Traverse is new Traverse_Proc (Process);
      --  The traversal procedure itself

      -------------
      -- Process --
      -------------

      function Process (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) not in N_Subexpr then
            return Skip;
         end if;

         Set_Do_Range_Check (N, False);

         case Nkind (N) is
            when N_And_Then =>
               Traverse (Left_Opnd (N));
               return Skip;

            when N_Attribute_Reference =>
               Set_Do_Overflow_Check (N, False);

            when N_Op =>
               Set_Do_Overflow_Check (N, False);

               case Nkind (N) is
                  when N_Op_Divide =>
                     Set_Do_Division_Check (N, False);

                  when N_Op_And =>
                     Set_Do_Length_Check (N, False);

                  when N_Op_Mod =>
                     Set_Do_Division_Check (N, False);

                  when N_Op_Or =>
                     Set_Do_Length_Check (N, False);

                  when N_Op_Rem =>
                     Set_Do_Division_Check (N, False);

                  when N_Op_Xor =>
                     Set_Do_Length_Check (N, False);

                  when others =>
                     null;
               end case;

            when N_Or_Else =>
               Traverse (Left_Opnd (N));
               return Skip;

            when N_Selected_Component =>
               Set_Do_Discriminant_Check (N, False);

            when N_Type_Conversion =>
               Set_Do_Length_Check   (N, False);
               Set_Do_Overflow_Check (N, False);

            when others =>
               null;
         end case;

         return OK;
      end Process;

   --  Start of processing for Remove_Checks

   begin
      Traverse (Expr);
   end Remove_Checks;

   ----------------------------
   -- Selected_Length_Checks --
   ----------------------------

   function Selected_Length_Checks
     (Expr       : Node_Id;
      Target_Typ : Entity_Id;
      Source_Typ : Entity_Id;
      Warn_Node  : Node_Id) return Check_Result
   is
      Loc         : constant Source_Ptr := Sloc (Expr);
      S_Typ       : Entity_Id;
      T_Typ       : Entity_Id;
      Expr_Actual : Node_Id;
      Exptyp      : Entity_Id;
      Cond        : Node_Id := Empty;
      Do_Access   : Boolean := False;
      Wnode       : Node_Id := Warn_Node;
      Ret_Result  : Check_Result := (Empty, Empty);
      Num_Checks  : Natural := 0;

      procedure Add_Check (N : Node_Id);
      --  Adds the action given to Ret_Result if N is non-Empty

      function Get_E_Length (E : Entity_Id; Indx : Nat) return Node_Id;
      --  Return E'Length (Indx)

      function Get_N_Length (N : Node_Id; Indx : Nat) return Node_Id;
      --  Return N'Length (Indx)

      function Same_Bounds (L : Node_Id; R : Node_Id) return Boolean;
      --  True for equal literals and for nodes that denote the same constant
      --  entity, even if its value is not a static constant. This includes the
      --  case of a discriminal reference within an init proc. Removes some
      --  obviously superfluous checks.

      function Length_E_Cond
        (Exptyp : Entity_Id;
         Typ    : Entity_Id;
         Indx   : Nat) return Node_Id;
      --  Returns expression to compute:
      --    Typ'Length /= Exptyp'Length

      function Length_N_Cond
        (Exp  : Node_Id;
         Typ  : Entity_Id;
         Indx : Nat) return Node_Id;
      --  Returns expression to compute:
      --    Typ'Length /= Exp'Length

      function Length_Mismatch_Info_Message
        (Left_Element_Count  : Uint;
         Right_Element_Count : Uint) return String;
      --  Returns a message indicating how many elements were expected
      --  (Left_Element_Count) and how many were found (Right_Element_Count).

      ---------------
      -- Add_Check --
      ---------------

      procedure Add_Check (N : Node_Id) is
      begin
         if Present (N) then

            --  We do not support inserting more than 2 checks on the same
            --  node. If this happens it means we have already added an
            --  unconditional raise, so we can skip the other checks safely
            --  since N will always raise an exception.

            if Num_Checks = 2 then
               return;
            end if;

            pragma Assert (Num_Checks <= 1);
            Num_Checks := Num_Checks + 1;
            Ret_Result (Num_Checks) := N;
         end if;
      end Add_Check;

      ------------------
      -- Get_E_Length --
      ------------------

      function Get_E_Length (E : Entity_Id; Indx : Nat) return Node_Id is
         SE : constant Entity_Id := Scope (E);
         N  : Node_Id;
         E1 : Entity_Id := E;

      begin
         if Ekind (Scope (E)) = E_Record_Type
           and then Has_Discriminants (Scope (E))
         then
            N := Build_Discriminal_Subtype_Of_Component (E);

            if Present (N) then
               Insert_Action (Expr, N);
               E1 := Defining_Identifier (N);
            end if;
         end if;

         if Ekind (E1) = E_String_Literal_Subtype then
            return
              Make_Integer_Literal (Loc,
                Intval => String_Literal_Length (E1));

         elsif SE /= Standard_Standard
           and then Ekind (Scope (SE)) = E_Protected_Type
           and then Has_Discriminants (Scope (SE))
           and then Has_Completion (Scope (SE))
           and then not Inside_Init_Proc
         then
            --  If the type whose length is needed is a private component
            --  constrained by a discriminant, we must expand the 'Length
            --  attribute into an explicit computation, using the discriminal
            --  of the current protected operation. This is because the actual
            --  type of the prival is constructed after the protected opera-
            --  tion has been fully expanded.

            declare
               Indx_Type : Node_Id;
               Bounds    : Range_Nodes;
               Do_Expand : Boolean := False;

            begin
               Indx_Type := First_Index (E);

               for J in 1 .. Indx - 1 loop
                  Next_Index (Indx_Type);
               end loop;

               Bounds := Get_Index_Bounds (Indx_Type);

               if Nkind (Bounds.First) = N_Identifier
                 and then Ekind (Entity (Bounds.First)) = E_In_Parameter
               then
                  Bounds.First := Get_Discriminal (E, Bounds.First);
                  Do_Expand := True;
               end if;

               if Nkind (Bounds.Last) = N_Identifier
                 and then Ekind (Entity (Bounds.Last)) = E_In_Parameter
               then
                  Bounds.Last := Get_Discriminal (E, Bounds.Last);
                  Do_Expand := True;
               end if;

               if Do_Expand then
                  if not Is_Entity_Name (Bounds.First) then
                     Bounds.First :=
                       Duplicate_Subexpr_No_Checks (Bounds.First);
                  end if;

                  if not Is_Entity_Name (Bounds.Last) then
                     Bounds.First := Duplicate_Subexpr_No_Checks (Bounds.Last);
                  end if;

                  N :=
                    Make_Op_Add (Loc,
                      Left_Opnd =>
                        Make_Op_Subtract (Loc,
                          Left_Opnd  => Bounds.Last,
                          Right_Opnd => Bounds.First),

                      Right_Opnd => Make_Integer_Literal (Loc, 1));
                  return N;

               else
                  N :=
                    Make_Attribute_Reference (Loc,
                      Attribute_Name => Name_Length,
                      Prefix =>
                        New_Occurrence_Of (E1, Loc));

                  if Indx > 1 then
                     Set_Expressions (N, New_List (
                       Make_Integer_Literal (Loc, Indx)));
                  end if;

                  return N;
               end if;
            end;

         else
            N :=
              Make_Attribute_Reference (Loc,
                Attribute_Name => Name_Length,
                Prefix =>
                  New_Occurrence_Of (E1, Loc));

            if Indx > 1 then
               Set_Expressions (N, New_List (
                 Make_Integer_Literal (Loc, Indx)));
            end if;

            return N;
         end if;
      end Get_E_Length;

      ------------------
      -- Get_N_Length --
      ------------------

      function Get_N_Length (N : Node_Id; Indx : Nat) return Node_Id is
      begin
         return
           Make_Attribute_Reference (Loc,
             Attribute_Name => Name_Length,
             Prefix =>
               Duplicate_Subexpr_No_Checks (N, Name_Req => True),
             Expressions => New_List (
               Make_Integer_Literal (Loc, Indx)));
      end Get_N_Length;

      -------------------
      -- Length_E_Cond --
      -------------------

      function Length_E_Cond
        (Exptyp : Entity_Id;
         Typ    : Entity_Id;
         Indx   : Nat) return Node_Id
      is
      begin
         return
           Make_Op_Ne (Loc,
             Left_Opnd  => Get_E_Length (Typ, Indx),
             Right_Opnd => Get_E_Length (Exptyp, Indx));
      end Length_E_Cond;

      -------------------
      -- Length_N_Cond --
      -------------------

      function Length_N_Cond
        (Exp  : Node_Id;
         Typ  : Entity_Id;
         Indx : Nat) return Node_Id
      is
      begin
         return
           Make_Op_Ne (Loc,
             Left_Opnd  => Get_E_Length (Typ, Indx),
             Right_Opnd => Get_N_Length (Exp, Indx));
      end Length_N_Cond;

      ----------------------------------
      -- Length_Mismatch_Info_Message --
      ----------------------------------

      function Length_Mismatch_Info_Message
        (Left_Element_Count  : Uint;
         Right_Element_Count : Uint) return String
      is

         function Plural_Vs_Singular_Ending (Count : Uint) return String;
         --  Returns an empty string if Count is 1; otherwise returns "s"

         function Plural_Vs_Singular_Ending (Count : Uint) return String is
         begin
            if Count = 1 then
               return "";
            else
               return "s";
            end if;
         end Plural_Vs_Singular_Ending;

      begin
         return "expected " & UI_Image (Left_Element_Count)
                  & " element"
                  & Plural_Vs_Singular_Ending (Left_Element_Count)
                  & "; found " & UI_Image (Right_Element_Count)
                  & " element"
                  & Plural_Vs_Singular_Ending (Right_Element_Count);
      end Length_Mismatch_Info_Message;

      -----------------
      -- Same_Bounds --
      -----------------

      function Same_Bounds (L : Node_Id; R : Node_Id) return Boolean is
      begin
         return
           (Nkind (L) = N_Integer_Literal
             and then Nkind (R) = N_Integer_Literal
             and then Intval (L) = Intval (R))

          or else
            (Is_Entity_Name (L)
              and then Ekind (Entity (L)) = E_Constant
              and then ((Is_Entity_Name (R)
                         and then Entity (L) = Entity (R))
                        or else
                       (Nkind (R) = N_Type_Conversion
                         and then Is_Entity_Name (Expression (R))
                         and then Entity (L) = Entity (Expression (R)))))

          or else
            (Is_Entity_Name (R)
              and then Ekind (Entity (R)) = E_Constant
              and then Nkind (L) = N_Type_Conversion
              and then Is_Entity_Name (Expression (L))
              and then Entity (R) = Entity (Expression (L)))

         or else
            (Is_Entity_Name (L)
              and then Is_Entity_Name (R)
              and then Entity (L) = Entity (R)
              and then Ekind (Entity (L)) = E_In_Parameter
              and then Inside_Init_Proc);
      end Same_Bounds;

   --  Start of processing for Selected_Length_Checks

   begin
      --  Checks will be applied only when generating code

      if not Expander_Active then
         return Ret_Result;
      end if;

      if Target_Typ = Any_Type
        or else Target_Typ = Any_Composite
        or else Raises_Constraint_Error (Expr)
      then
         return Ret_Result;
      end if;

      if No (Wnode) then
         Wnode := Expr;
      end if;

      T_Typ := Target_Typ;

      if No (Source_Typ) then
         S_Typ := Etype (Expr);
      else
         S_Typ := Source_Typ;
      end if;

      if S_Typ = Any_Type or else S_Typ = Any_Composite then
         return Ret_Result;
      end if;

      if Is_Access_Type (T_Typ) and then Is_Access_Type (S_Typ) then
         S_Typ := Designated_Type (S_Typ);
         T_Typ := Designated_Type (T_Typ);
         Do_Access := True;

         --  A simple optimization for the null case

         if Known_Null (Expr) then
            return Ret_Result;
         end if;
      end if;

      if Is_Array_Type (T_Typ) and then Is_Array_Type (S_Typ) then
         if Is_Constrained (T_Typ) then

            --  The checking code to be generated will freeze the corresponding
            --  array type. However, we must freeze the type now, so that the
            --  freeze node does not appear within the generated if expression,
            --  but ahead of it.

            Freeze_Before (Expr, T_Typ);

            Expr_Actual := Get_Referenced_Object (Expr);
            Exptyp      := Get_Actual_Subtype (Expr);

            if Is_Access_Type (Exptyp) then
               Exptyp := Designated_Type (Exptyp);
            end if;

            --  String_Literal case. This needs to be handled specially be-
            --  cause no index types are available for string literals. The
            --  condition is simply:

            --    T_Typ'Length = string-literal-length

            if Nkind (Expr_Actual) = N_String_Literal
              and then Ekind (Etype (Expr_Actual)) = E_String_Literal_Subtype
            then
               Cond :=
                 Make_Op_Ne (Loc,
                   Left_Opnd  => Get_E_Length (T_Typ, 1),
                   Right_Opnd =>
                     Make_Integer_Literal (Loc,
                       Intval =>
                         String_Literal_Length (Etype (Expr_Actual))));

            --  General array case. Here we have a usable actual subtype for
            --  the expression, and the condition is built from the two types
            --  (Do_Length):

            --     T_Typ'Length     /= Exptyp'Length     or else
            --     T_Typ'Length (2) /= Exptyp'Length (2) or else
            --     T_Typ'Length (3) /= Exptyp'Length (3) or else
            --     ...

            elsif Is_Constrained (Exptyp) then
               declare
                  Ndims : constant Nat := Number_Dimensions (T_Typ);

                  L_Index  : Node_Id;
                  R_Index  : Node_Id;
                  L_Bounds : Range_Nodes;
                  R_Bounds : Range_Nodes;
                  L_Length : Uint;
                  R_Length : Uint;
                  Ref_Node : Node_Id;

               begin
                  --  At the library level, we need to ensure that the type of
                  --  the object is elaborated before the check itself is
                  --  emitted. This is only done if the object is in the
                  --  current compilation unit, otherwise the type is frozen
                  --  and elaborated in its unit.

                  if Is_Itype (Exptyp)
                    and then
                      Ekind (Cunit_Entity (Current_Sem_Unit)) = E_Package
                    and then
                      not In_Package_Body (Cunit_Entity (Current_Sem_Unit))
                    and then In_Open_Scopes (Scope (Exptyp))
                  then
                     Ref_Node := Make_Itype_Reference (Sloc (Expr));
                     Set_Itype (Ref_Node, Exptyp);
                     Insert_Action (Expr, Ref_Node);
                  end if;

                  L_Index := First_Index (T_Typ);
                  R_Index := First_Index (Exptyp);

                  for Indx in 1 .. Ndims loop
                     if not (Nkind (L_Index) = N_Raise_Constraint_Error
                               or else
                             Nkind (R_Index) = N_Raise_Constraint_Error)
                     then
                        L_Bounds := Get_Index_Bounds (L_Index);
                        R_Bounds := Get_Index_Bounds (R_Index);

                        --  Deal with compile time length check. Note that we
                        --  skip this in the access case, because the access
                        --  value may be null, so we cannot know statically.

                        if not Do_Access
                          and then Compile_Time_Known_Value (L_Bounds.First)
                          and then Compile_Time_Known_Value (L_Bounds.Last)
                          and then Compile_Time_Known_Value (R_Bounds.First)
                          and then Compile_Time_Known_Value (R_Bounds.Last)
                        then
                           if Expr_Value (L_Bounds.Last) >=
                              Expr_Value (L_Bounds.First)
                           then
                              L_Length := Expr_Value (L_Bounds.Last) -
                                          Expr_Value (L_Bounds.First) + 1;
                           else
                              L_Length := UI_From_Int (0);
                           end if;

                           if Expr_Value (R_Bounds.Last) >=
                              Expr_Value (R_Bounds.First)
                           then
                              R_Length := Expr_Value (R_Bounds.Last) -
                                          Expr_Value (R_Bounds.First) + 1;
                           else
                              R_Length := UI_From_Int (0);
                           end if;

                           if L_Length > R_Length then
                              Add_Check
                                (Compile_Time_Constraint_Error
                                  (Wnode, "too few elements for}??", T_Typ,
                                   Extra_Msg => Length_Mismatch_Info_Message
                                                  (L_Length, R_Length)));

                           elsif L_Length < R_Length then
                              Add_Check
                                (Compile_Time_Constraint_Error
                                  (Wnode, "too many elements for}??", T_Typ,
                                   Extra_Msg => Length_Mismatch_Info_Message
                                                  (L_Length, R_Length)));
                           end if;

                        --  The comparison for an individual index subtype
                        --  is omitted if the corresponding index subtypes
                        --  statically match, since the result is known to
                        --  be true. Note that this test is worth while even
                        --  though we do static evaluation, because non-static
                        --  subtypes can statically match.

                        elsif not
                          Subtypes_Statically_Match
                            (Etype (L_Index), Etype (R_Index))

                          and then not
                            (Same_Bounds (L_Bounds.First, R_Bounds.First)
                              and then
                             Same_Bounds (L_Bounds.Last, R_Bounds.Last))
                        then
                           Evolve_Or_Else
                             (Cond, Length_E_Cond (Exptyp, T_Typ, Indx));
                        end if;

                        Next (L_Index);
                        Next (R_Index);
                     end if;
                  end loop;
               end;

            --  Handle cases where we do not get a usable actual subtype that
            --  is constrained. This happens for example in the function call
            --  and explicit dereference cases. In these cases, we have to get
            --  the length or range from the expression itself, making sure we
            --  do not evaluate it more than once.

            --  Here Expr is the original expression, or more properly the
            --  result of applying Duplicate_Expr to the original tree, forcing
            --  the result to be a name.

            else
               declare
                  Ndims : constant Pos := Number_Dimensions (T_Typ);

               begin
                  --  Build the condition for the explicit dereference case

                  for Indx in 1 .. Ndims loop
                     Evolve_Or_Else
                       (Cond, Length_N_Cond (Expr, T_Typ, Indx));
                  end loop;
               end;
            end if;
         end if;
      end if;

      --  Construct the test and insert into the tree

      if Present (Cond) then
         if Do_Access then
            Cond := Guard_Access (Cond, Loc, Expr);
         end if;

         Add_Check
           (Make_Raise_Constraint_Error (Loc,
              Condition => Cond,
              Reason => CE_Length_Check_Failed));
      end if;

      return Ret_Result;
   end Selected_Length_Checks;

   ---------------------------
   -- Selected_Range_Checks --
   ---------------------------

   function Selected_Range_Checks
     (Expr       : Node_Id;
      Target_Typ : Entity_Id;
      Source_Typ : Entity_Id;
      Warn_Node  : Node_Id) return Check_Result
   is
      Loc         : constant Source_Ptr := Sloc (Expr);
      S_Typ       : Entity_Id;
      T_Typ       : Entity_Id;
      Expr_Actual : Node_Id;
      Exptyp      : Entity_Id;
      Cond        : Node_Id := Empty;
      Do_Access   : Boolean := False;
      Wnode       : Node_Id := Warn_Node;
      Ret_Result  : Check_Result := (Empty, Empty);
      Num_Checks  : Natural := 0;

      procedure Add_Check (N : Node_Id);
      --  Adds the action given to Ret_Result if N is non-Empty

      function Discrete_Range_Cond
        (Exp : Node_Id;
         Typ : Entity_Id) return Node_Id;
      --  Returns expression to compute:
      --    Low_Bound (Exp) < Typ'First
      --      or else
      --    High_Bound (Exp) > Typ'Last

      function Discrete_Expr_Cond
        (Exp : Node_Id;
         Typ : Entity_Id) return Node_Id;
      --  Returns expression to compute:
      --    Exp < Typ'First
      --      or else
      --    Exp > Typ'Last

      function Get_E_First_Or_Last
        (Loc  : Source_Ptr;
         E    : Entity_Id;
         Indx : Nat;
         Nam  : Name_Id) return Node_Id;
      --  Returns an attribute reference
      --    E'First or E'Last
      --  with a source location of Loc.
      --
      --  Nam is Name_First or Name_Last, according to which attribute is
      --  desired. If Indx is non-zero, it is passed as a literal in the
      --  Expressions of the attribute reference (identifying the desired
      --  array dimension).

      function Get_N_First (N : Node_Id; Indx : Nat) return Node_Id;
      function Get_N_Last  (N : Node_Id; Indx : Nat) return Node_Id;
      --  Returns expression to compute:
      --    N'First or N'Last using Duplicate_Subexpr_No_Checks

      function Range_E_Cond
        (Exptyp : Entity_Id;
         Typ    : Entity_Id;
         Indx   : Nat)
         return   Node_Id;
      --  Returns expression to compute:
      --    Exptyp'First < Typ'First or else Exptyp'Last > Typ'Last

      function Range_Equal_E_Cond
        (Exptyp : Entity_Id;
         Typ    : Entity_Id;
         Indx   : Nat) return Node_Id;
      --  Returns expression to compute:
      --    Exptyp'First /= Typ'First or else Exptyp'Last /= Typ'Last

      function Range_N_Cond
        (Exp  : Node_Id;
         Typ  : Entity_Id;
         Indx : Nat) return Node_Id;
      --  Return expression to compute:
      --    Exp'First < Typ'First or else Exp'Last > Typ'Last

      ---------------
      -- Add_Check --
      ---------------

      procedure Add_Check (N : Node_Id) is
      begin
         if Present (N) then

            --  We do not support inserting more than 2 checks on the same
            --  node. If this happens it means we have already added an
            --  unconditional raise, so we can skip the other checks safely
            --  since N will always raise an exception.

            if Num_Checks = 2 then
               return;
            end if;

            pragma Assert (Num_Checks <= 1);
            Num_Checks := Num_Checks + 1;
            Ret_Result (Num_Checks) := N;
         end if;
      end Add_Check;

      -------------------------
      -- Discrete_Expr_Cond --
      -------------------------

      function Discrete_Expr_Cond
        (Exp : Node_Id;
         Typ : Entity_Id) return Node_Id
      is
      begin
         return
           Make_Or_Else (Loc,
             Left_Opnd =>
               Make_Op_Lt (Loc,
                 Left_Opnd =>
                   Convert_To (Base_Type (Typ),
                     Duplicate_Subexpr_No_Checks (Exp)),
                 Right_Opnd =>
                   Convert_To (Base_Type (Typ),
                               Get_E_First_Or_Last (Loc, Typ, 0, Name_First))),

             Right_Opnd =>
               Make_Op_Gt (Loc,
                 Left_Opnd =>
                   Convert_To (Base_Type (Typ),
                     Duplicate_Subexpr_No_Checks (Exp)),
                 Right_Opnd =>
                   Convert_To
                     (Base_Type (Typ),
                      Get_E_First_Or_Last (Loc, Typ, 0, Name_Last))));
      end Discrete_Expr_Cond;

      -------------------------
      -- Discrete_Range_Cond --
      -------------------------

      function Discrete_Range_Cond
        (Exp : Node_Id;
         Typ : Entity_Id) return Node_Id
      is
         LB : Node_Id := Low_Bound (Exp);
         HB : Node_Id := High_Bound (Exp);

         Left_Opnd  : Node_Id;
         Right_Opnd : Node_Id;

      begin
         if Nkind (LB) = N_Identifier
           and then Ekind (Entity (LB)) = E_Discriminant
         then
            LB := New_Occurrence_Of (Discriminal (Entity (LB)), Loc);
         end if;

         --  If the index type has a fixed lower bound, then we require an
         --  exact match of the range's lower bound against that fixed lower
         --  bound.

         if Is_Fixed_Lower_Bound_Index_Subtype (Typ) then
            Left_Opnd :=
              Make_Op_Ne (Loc,
                Left_Opnd  =>
                  Convert_To
                    (Base_Type (Typ), Duplicate_Subexpr_No_Checks (LB)),

                Right_Opnd =>
                  Convert_To
                    (Base_Type (Typ),
                     Get_E_First_Or_Last (Loc, Typ, 0, Name_First)));

         --  Otherwise we do the expected less-than comparison

         else
            Left_Opnd :=
              Make_Op_Lt (Loc,
                Left_Opnd  =>
                  Convert_To
                    (Base_Type (Typ), Duplicate_Subexpr_No_Checks (LB)),

                Right_Opnd =>
                  Convert_To
                    (Base_Type (Typ),
                     Get_E_First_Or_Last (Loc, Typ, 0, Name_First)));
         end if;

         if Nkind (HB) = N_Identifier
           and then Ekind (Entity (HB)) = E_Discriminant
         then
            HB := New_Occurrence_Of (Discriminal (Entity (HB)), Loc);
         end if;

         Right_Opnd :=
           Make_Op_Gt (Loc,
             Left_Opnd  =>
               Convert_To
                 (Base_Type (Typ), Duplicate_Subexpr_No_Checks (HB)),

             Right_Opnd =>
               Convert_To
                 (Base_Type (Typ),
                  Get_E_First_Or_Last (Loc, Typ, 0, Name_Last)));

         return Make_Or_Else (Loc, Left_Opnd, Right_Opnd);
      end Discrete_Range_Cond;

      -------------------------
      -- Get_E_First_Or_Last --
      -------------------------

      function Get_E_First_Or_Last
        (Loc  : Source_Ptr;
         E    : Entity_Id;
         Indx : Nat;
         Nam  : Name_Id) return Node_Id
      is
         Exprs : List_Id;
      begin
         if Indx > 0 then
            Exprs := New_List (Make_Integer_Literal (Loc, UI_From_Int (Indx)));
         else
            Exprs := No_List;
         end if;

         return Make_Attribute_Reference (Loc,
                  Prefix         => New_Occurrence_Of (E, Loc),
                  Attribute_Name => Nam,
                  Expressions    => Exprs);
      end Get_E_First_Or_Last;

      -----------------
      -- Get_N_First --
      -----------------

      function Get_N_First (N : Node_Id; Indx : Nat) return Node_Id is
      begin
         return
           Make_Attribute_Reference (Loc,
             Attribute_Name => Name_First,
             Prefix =>
               Duplicate_Subexpr_No_Checks (N, Name_Req => True),
             Expressions => New_List (
               Make_Integer_Literal (Loc, Indx)));
      end Get_N_First;

      ----------------
      -- Get_N_Last --
      ----------------

      function Get_N_Last (N : Node_Id; Indx : Nat) return Node_Id is
      begin
         return
           Make_Attribute_Reference (Loc,
             Attribute_Name => Name_Last,
             Prefix =>
               Duplicate_Subexpr_No_Checks (N, Name_Req => True),
             Expressions => New_List (
              Make_Integer_Literal (Loc, Indx)));
      end Get_N_Last;

      ------------------
      -- Range_E_Cond --
      ------------------

      function Range_E_Cond
        (Exptyp : Entity_Id;
         Typ    : Entity_Id;
         Indx   : Nat) return Node_Id
      is
      begin
         return
           Make_Or_Else (Loc,
             Left_Opnd =>
               Make_Op_Lt (Loc,
                 Left_Opnd   =>
                   Get_E_First_Or_Last (Loc, Exptyp, Indx, Name_First),
                 Right_Opnd  =>
                   Get_E_First_Or_Last (Loc, Typ, Indx, Name_First)),

             Right_Opnd =>
               Make_Op_Gt (Loc,
                 Left_Opnd   =>
                   Get_E_First_Or_Last (Loc, Exptyp, Indx, Name_Last),
                 Right_Opnd  =>
                   Get_E_First_Or_Last (Loc, Typ, Indx, Name_Last)));
      end Range_E_Cond;

      ------------------------
      -- Range_Equal_E_Cond --
      ------------------------

      function Range_Equal_E_Cond
        (Exptyp : Entity_Id;
         Typ    : Entity_Id;
         Indx   : Nat) return Node_Id
      is
      begin
         return
           Make_Or_Else (Loc,
             Left_Opnd =>
               Make_Op_Ne (Loc,
                 Left_Opnd   =>
                   Get_E_First_Or_Last (Loc, Exptyp, Indx, Name_First),
                 Right_Opnd  =>
                   Get_E_First_Or_Last (Loc, Typ, Indx, Name_First)),

             Right_Opnd =>
               Make_Op_Ne (Loc,
                 Left_Opnd   =>
                   Get_E_First_Or_Last (Loc, Exptyp, Indx, Name_Last),
                 Right_Opnd  =>
                   Get_E_First_Or_Last (Loc, Typ, Indx, Name_Last)));
      end Range_Equal_E_Cond;

      ------------------
      -- Range_N_Cond --
      ------------------

      function Range_N_Cond
        (Exp  : Node_Id;
         Typ  : Entity_Id;
         Indx : Nat) return Node_Id
      is
      begin
         return
           Make_Or_Else (Loc,
             Left_Opnd =>
               Make_Op_Lt (Loc,
                 Left_Opnd  =>
                   Get_N_First (Exp, Indx),
                 Right_Opnd =>
                   Get_E_First_Or_Last (Loc, Typ, Indx, Name_First)),

             Right_Opnd =>
               Make_Op_Gt (Loc,
                 Left_Opnd  =>
                   Get_N_Last (Exp, Indx),
                 Right_Opnd =>
                   Get_E_First_Or_Last (Loc, Typ, Indx, Name_Last)));
      end Range_N_Cond;

      function "<" (Left, Right : Node_Id) return Boolean
      is (if Is_Floating_Point_Type (S_Typ)
          then Expr_Value_R (Left) < Expr_Value_R (Right)
          else Expr_Value   (Left) < Expr_Value   (Right));
      --  Convenience comparison function of integer or floating point
      --  values.

   --  Start of processing for Selected_Range_Checks

   begin
      --  Checks will be applied only when generating code. In GNATprove mode,
      --  we do not apply the checks, but we still call Selected_Range_Checks
      --  outside of generics to possibly issue errors on SPARK code when a
      --  run-time error can be detected at compile time.

      if Inside_A_Generic or (not GNATprove_Mode and not Expander_Active) then
         return Ret_Result;
      end if;

      if Target_Typ = Any_Type
        or else Target_Typ = Any_Composite
        or else Raises_Constraint_Error (Expr)
      then
         return Ret_Result;
      end if;

      if No (Wnode) then
         Wnode := Expr;
      end if;

      T_Typ := Target_Typ;

      if No (Source_Typ) then
         S_Typ := Etype (Expr);
      else
         S_Typ := Source_Typ;
      end if;

      if S_Typ = Any_Type or else S_Typ = Any_Composite then
         return Ret_Result;
      end if;

      --  The order of evaluating T_Typ before S_Typ seems to be critical
      --  because S_Typ can be derived from Etype (Expr), if it's not passed
      --  in, and since Node can be an N_Range node, it might be invalid.
      --  Should there be an assert check somewhere for taking the Etype of
      --  an N_Range node ???

      if Is_Access_Type (T_Typ) and then Is_Access_Type (S_Typ) then
         S_Typ := Designated_Type (S_Typ);
         T_Typ := Designated_Type (T_Typ);
         Do_Access := True;

         --  A simple optimization for the null case

         if Known_Null (Expr) then
            return Ret_Result;
         end if;
      end if;

      --  For an N_Range Node, check for a null range and then if not
      --  null generate a range check action.

      if Nkind (Expr) = N_Range then

         --  There's no point in checking a range against itself

         if Expr = Scalar_Range (T_Typ) then
            return Ret_Result;
         end if;

         declare
            T_LB       : constant Node_Id := Type_Low_Bound  (T_Typ);
            T_HB       : constant Node_Id := Type_High_Bound (T_Typ);
            Known_T_LB : constant Boolean := Compile_Time_Known_Value (T_LB);
            Known_T_HB : constant Boolean := Compile_Time_Known_Value (T_HB);

            LB          : Node_Id := Low_Bound (Expr);
            HB          : Node_Id := High_Bound (Expr);
            Known_LB    : Boolean := False;
            Known_HB    : Boolean := False;
            Check_Added : Boolean := False;

            Out_Of_Range_L : Boolean := False;
            Out_Of_Range_H : Boolean := False;

         begin
            --  Compute what is known at compile time

            if Known_T_LB and Known_T_HB then
               if Compile_Time_Known_Value (LB) then
                  Known_LB := True;

               --  There's no point in checking that a bound is within its
               --  own range so pretend that it is known in this case. First
               --  deal with low bound.

               elsif Ekind (Etype (LB)) = E_Signed_Integer_Subtype
                 and then Scalar_Range (Etype (LB)) = Scalar_Range (T_Typ)
               then
                  LB := T_LB;
                  Known_LB := True;
               end if;

               --  Likewise for the high bound

               if Compile_Time_Known_Value (HB) then
                  Known_HB := True;

               elsif Ekind (Etype (HB)) = E_Signed_Integer_Subtype
                 and then Scalar_Range (Etype (HB)) = Scalar_Range (T_Typ)
               then
                  HB := T_HB;
                  Known_HB := True;
               end if;
            end if;

            --  Check for the simple cases where we can do the check at
            --  compile time. This is skipped if we have an access type, since
            --  the access value may be null.

            if not Do_Access and then Not_Null_Range (LB, HB) then
               if Known_LB then
                  if Known_T_LB then
                     Out_Of_Range_L := LB < T_LB;
                  end if;

                  if Known_T_HB and not Out_Of_Range_L then
                     Out_Of_Range_L := T_HB < LB;
                  end if;

                  if Out_Of_Range_L then
                     if No (Warn_Node) then
                        Add_Check
                          (Compile_Time_Constraint_Error
                             (Low_Bound (Expr),
                              "static value out of range of}??", T_Typ));
                        Check_Added := True;

                     else
                        Add_Check
                          (Compile_Time_Constraint_Error
                            (Wnode,
                             "static range out of bounds of}??", T_Typ));
                        Check_Added := True;
                     end if;
                  end if;
               end if;

               --  Flag the case of a fixed-lower-bound index where the static
               --  bounds are not equal.

               if not Check_Added
                 and then Is_Fixed_Lower_Bound_Index_Subtype (T_Typ)
                 and then Expr_Value (LB) /= Expr_Value (T_LB)
               then
                  Add_Check
                    (Compile_Time_Constraint_Error
                       ((if Present (Warn_Node)
                        then Warn_Node else Low_Bound (Expr)),
                        "static value does not equal lower bound of}??",
                        T_Typ));
                  Check_Added := True;
               end if;

               if Known_HB then
                  if Known_T_HB then
                     Out_Of_Range_H := T_HB < HB;
                  end if;

                  if Known_T_LB and not Out_Of_Range_H then
                     Out_Of_Range_H := HB < T_LB;
                  end if;

                  if Out_Of_Range_H then
                     if No (Warn_Node) then
                        Add_Check
                          (Compile_Time_Constraint_Error
                             (High_Bound (Expr),
                              "static value out of range of}??", T_Typ));
                        Check_Added := True;

                     else
                        Add_Check
                          (Compile_Time_Constraint_Error
                             (Wnode,
                              "static range out of bounds of}??", T_Typ));
                        Check_Added := True;
                     end if;
                  end if;
               end if;
            end if;

            --  Check for the case where not everything is static

            if not Check_Added
              and then
                (Do_Access
                  or else not Known_T_LB
                  or else not Known_LB
                  or else not Known_T_HB
                  or else not Known_HB)
            then
               declare
                  LB : Node_Id := Low_Bound (Expr);
                  HB : Node_Id := High_Bound (Expr);

               begin
                  --  If either bound is a discriminant and we are within the
                  --  record declaration, it is a use of the discriminant in a
                  --  constraint of a component, and nothing can be checked
                  --  here. The check will be emitted within the init proc.
                  --  Before then, the discriminal has no real meaning.
                  --  Similarly, if the entity is a discriminal, there is no
                  --  check to perform yet.

                  --  The same holds within a discriminated synchronized type,
                  --  where the discriminant may constrain a component or an
                  --  entry family.

                  if Nkind (LB) = N_Identifier
                    and then Denotes_Discriminant (LB, True)
                  then
                     if Current_Scope = Scope (Entity (LB))
                       or else Is_Concurrent_Type (Current_Scope)
                       or else Ekind (Entity (LB)) /= E_Discriminant
                     then
                        return Ret_Result;
                     else
                        LB :=
                          New_Occurrence_Of (Discriminal (Entity (LB)), Loc);
                     end if;
                  end if;

                  if Nkind (HB) = N_Identifier
                    and then Denotes_Discriminant (HB, True)
                  then
                     if Current_Scope = Scope (Entity (HB))
                       or else Is_Concurrent_Type (Current_Scope)
                       or else Ekind (Entity (HB)) /= E_Discriminant
                     then
                        return Ret_Result;
                     else
                        HB :=
                          New_Occurrence_Of (Discriminal (Entity (HB)), Loc);
                     end if;
                  end if;

                  Cond := Discrete_Range_Cond (Expr, T_Typ);
                  Set_Paren_Count (Cond, 1);

                  Cond :=
                    Make_And_Then (Loc,
                      Left_Opnd =>
                        Make_Op_Ge (Loc,
                          Left_Opnd  =>
                            Convert_To (Base_Type (Etype (HB)),
                              Duplicate_Subexpr_No_Checks (HB)),
                          Right_Opnd =>
                            Convert_To (Base_Type (Etype (LB)),
                              Duplicate_Subexpr_No_Checks (LB))),
                      Right_Opnd => Cond);
               end;
            end if;
         end;

      elsif Is_Scalar_Type (S_Typ) then

         --  This somewhat duplicates what Apply_Scalar_Range_Check does,
         --  except the above simply sets a flag in the node and lets the
         --  check be generated based on the Etype of the expression.
         --  Sometimes, however we want to do a dynamic check against an
         --  arbitrary target type, so we do that here.

         if Ekind (Base_Type (S_Typ)) /= Ekind (Base_Type (T_Typ)) then
            Cond := Discrete_Expr_Cond (Expr, T_Typ);

         --  For literals, we can tell if the constraint error will be
         --  raised at compile time, so we never need a dynamic check, but
         --  if the exception will be raised, then post the usual warning,
         --  and replace the literal with a raise constraint error
         --  expression. As usual, skip this for access types

         elsif Compile_Time_Known_Value (Expr) and then not Do_Access then
            if Is_Out_Of_Range (Expr, T_Typ) then

               --  Bounds of the type are static and the literal is out of
               --  range so output a warning message.

               if No (Warn_Node) then
                  Add_Check
                    (Compile_Time_Constraint_Error
                       (Expr, "static value out of range of}??", T_Typ));

               else
                  Add_Check
                    (Compile_Time_Constraint_Error
                       (Wnode, "static value out of range of}??", T_Typ));
               end if;
            else
               Cond := Discrete_Expr_Cond (Expr, T_Typ);
            end if;

         --  Here for the case of a non-static expression, we need a runtime
         --  check unless the source type range is guaranteed to be in the
         --  range of the target type.

         else
            if not In_Subrange_Of (S_Typ, T_Typ) then
               Cond := Discrete_Expr_Cond (Expr, T_Typ);
            end if;
         end if;
      end if;

      if Is_Array_Type (T_Typ) and then Is_Array_Type (S_Typ) then
         if Is_Constrained (T_Typ) then
            Expr_Actual := Get_Referenced_Object (Expr);
            Exptyp      := Get_Actual_Subtype (Expr_Actual);

            if Is_Access_Type (Exptyp) then
               Exptyp := Designated_Type (Exptyp);
            end if;

            --  String_Literal case. This needs to be handled specially be-
            --  cause no index types are available for string literals. The
            --  condition is simply:

            --    T_Typ'Length = string-literal-length

            if Nkind (Expr_Actual) = N_String_Literal then
               null;

            --  General array case. Here we have a usable actual subtype for
            --  the expression, and the condition is built from the two types

            --     T_Typ'First     < Exptyp'First     or else
            --     T_Typ'Last      > Exptyp'Last      or else
            --     T_Typ'First(1)  < Exptyp'First(1)  or else
            --     T_Typ'Last(1)   > Exptyp'Last(1)   or else
            --     ...

            elsif Is_Constrained (Exptyp) then
               declare
                  Ndims : constant Pos := Number_Dimensions (T_Typ);

                  L_Index : Node_Id;
                  R_Index : Node_Id;

               begin
                  L_Index := First_Index (T_Typ);
                  R_Index := First_Index (Exptyp);

                  for Indx in 1 .. Ndims loop
                     if not (Nkind (L_Index) = N_Raise_Constraint_Error
                               or else
                             Nkind (R_Index) = N_Raise_Constraint_Error)
                     then
                        --  Deal with compile time length check. Note that we
                        --  skip this in the access case, because the access
                        --  value may be null, so we cannot know statically.

                        if not
                          Subtypes_Statically_Match
                            (Etype (L_Index), Etype (R_Index))
                        then
                           --  If the target type is constrained then we
                           --  have to check for exact equality of bounds
                           --  (required for qualified expressions).

                           if Is_Constrained (T_Typ) then
                              Evolve_Or_Else
                                (Cond,
                                 Range_Equal_E_Cond (Exptyp, T_Typ, Indx));
                           else
                              Evolve_Or_Else
                                (Cond, Range_E_Cond (Exptyp, T_Typ, Indx));
                           end if;
                        end if;

                        Next (L_Index);
                        Next (R_Index);
                     end if;
                  end loop;
               end;

            --  Handle cases where we do not get a usable actual subtype that
            --  is constrained. This happens for example in the function call
            --  and explicit dereference cases. In these cases, we have to get
            --  the length or range from the expression itself, making sure we
            --  do not evaluate it more than once.

            --  Here Expr is the original expression, or more properly the
            --  result of applying Duplicate_Expr to the original tree,
            --  forcing the result to be a name.

            else
               declare
                  Ndims : constant Pos := Number_Dimensions (T_Typ);

               begin
                  --  Build the condition for the explicit dereference case

                  for Indx in 1 .. Ndims loop
                     Evolve_Or_Else
                       (Cond, Range_N_Cond (Expr, T_Typ, Indx));
                  end loop;
               end;
            end if;

         --  If the context is a qualified_expression where the subtype is
         --  an unconstrained array subtype with fixed-lower-bound indexes,
         --  then consistency checks must be done between the lower bounds
         --  of any such indexes and the corresponding lower bounds of the
         --  qualified array object.

         elsif Is_Fixed_Lower_Bound_Array_Subtype (T_Typ)
           and then Nkind (Parent (Expr)) = N_Qualified_Expression
           and then not Do_Access
         then
            declare
               Ndims : constant Pos := Number_Dimensions (T_Typ);

               Qual_Index : Node_Id;
               Expr_Index : Node_Id;

            begin
               Expr_Actual := Get_Referenced_Object (Expr);
               Exptyp      := Get_Actual_Subtype (Expr_Actual);

               Qual_Index := First_Index (T_Typ);
               Expr_Index := First_Index (Exptyp);

               for Indx in 1 .. Ndims loop
                  if Nkind (Expr_Index) /= N_Raise_Constraint_Error then

                     --  If this index of the qualifying array subtype has
                     --  a fixed lower bound, then apply a check that the
                     --  corresponding lower bound of the array expression
                     --  is equal to it.

                     if Is_Fixed_Lower_Bound_Index_Subtype (Etype (Qual_Index))
                     then
                        Evolve_Or_Else
                          (Cond,
                           Make_Op_Ne (Loc,
                             Left_Opnd   =>
                               Get_E_First_Or_Last
                                 (Loc, Exptyp, Indx, Name_First),
                             Right_Opnd  =>
                               New_Copy_Tree
                                 (Type_Low_Bound (Etype (Qual_Index)))));
                     end if;

                     Next (Qual_Index);
                     Next (Expr_Index);
                  end if;
               end loop;
            end;

         else
            --  For a conversion to an unconstrained array type, generate an
            --  Action to check that the bounds of the source value are within
            --  the constraints imposed by the target type (RM 4.6(38)). No
            --  check is needed for a conversion to an access to unconstrained
            --  array type, as 4.6(24.15/2) requires the designated subtypes
            --  of the two access types to statically match.

            if Nkind (Parent (Expr)) = N_Type_Conversion
              and then not Do_Access
            then
               declare
                  Opnd_Index : Node_Id;
                  Targ_Index : Node_Id;
                  Opnd_Range : Node_Id;

               begin
                  Opnd_Index := First_Index (Get_Actual_Subtype (Expr));
                  Targ_Index := First_Index (T_Typ);
                  while Present (Opnd_Index) loop

                     --  If the index is a range, use its bounds. If it is an
                     --  entity (as will be the case if it is a named subtype
                     --  or an itype created for a slice) retrieve its range.

                     if Is_Entity_Name (Opnd_Index)
                       and then Is_Type (Entity (Opnd_Index))
                     then
                        Opnd_Range := Scalar_Range (Entity (Opnd_Index));
                     else
                        Opnd_Range := Opnd_Index;
                     end if;

                     if Nkind (Opnd_Range) = N_Range then
                        if  Is_In_Range
                             (Low_Bound (Opnd_Range), Etype (Targ_Index),
                              Assume_Valid => True)
                          and then
                            Is_In_Range
                             (High_Bound (Opnd_Range), Etype (Targ_Index),
                              Assume_Valid => True)
                        then
                           null;

                        --  If null range, no check needed

                        elsif
                          Compile_Time_Known_Value (High_Bound (Opnd_Range))
                            and then
                          Compile_Time_Known_Value (Low_Bound (Opnd_Range))
                            and then
                              Expr_Value (High_Bound (Opnd_Range)) <
                                  Expr_Value (Low_Bound (Opnd_Range))
                        then
                           null;

                        elsif Is_Out_Of_Range
                                (Low_Bound (Opnd_Range), Etype (Targ_Index),
                                 Assume_Valid => True)
                          or else
                              Is_Out_Of_Range
                                (High_Bound (Opnd_Range), Etype (Targ_Index),
                                 Assume_Valid => True)
                        then
                           Add_Check
                             (Compile_Time_Constraint_Error
                               (Wnode, "value out of range of}??", T_Typ));

                        else
                           Evolve_Or_Else
                             (Cond,
                              Discrete_Range_Cond
                                (Opnd_Range, Etype (Targ_Index)));
                        end if;
                     end if;

                     Next_Index (Opnd_Index);
                     Next_Index (Targ_Index);
                  end loop;
               end;
            end if;
         end if;
      end if;

      --  Construct the test and insert into the tree

      if Present (Cond) then
         if Do_Access then
            Cond := Guard_Access (Cond, Loc, Expr);
         end if;

         Add_Check
           (Make_Raise_Constraint_Error (Loc,
             Condition => Cond,
             Reason    => CE_Range_Check_Failed));
      end if;

      return Ret_Result;
   end Selected_Range_Checks;

   -------------------------------
   -- Storage_Checks_Suppressed --
   -------------------------------

   function Storage_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E) and then Checks_May_Be_Suppressed (E) then
         return Is_Check_Suppressed (E, Storage_Check);
      else
         return Scope_Suppress.Suppress (Storage_Check);
      end if;
   end Storage_Checks_Suppressed;

   ---------------------------
   -- Tag_Checks_Suppressed --
   ---------------------------

   function Tag_Checks_Suppressed (E : Entity_Id) return Boolean is
   begin
      if Present (E)
        and then Checks_May_Be_Suppressed (E)
      then
         return Is_Check_Suppressed (E, Tag_Check);
      else
         return Scope_Suppress.Suppress (Tag_Check);
      end if;
   end Tag_Checks_Suppressed;

   ---------------------------------------
   -- Validate_Alignment_Check_Warnings --
   ---------------------------------------

   procedure Validate_Alignment_Check_Warnings is
   begin
      for J in Alignment_Warnings.First .. Alignment_Warnings.Last loop
         declare
            AWR : Alignment_Warnings_Record
                    renames Alignment_Warnings.Table (J);
         begin
            if Known_Alignment (AWR.E)
              and then ((Present (AWR.A)
                          and then AWR.A mod Alignment (AWR.E) = 0)
                        or else (Present (AWR.P)
                                  and then Has_Compatible_Alignment
                                             (AWR.E, AWR.P, True) =
                                               Known_Compatible))
            then
               Delete_Warning_And_Continuations (AWR.W);
            end if;
         end;
      end loop;
   end Validate_Alignment_Check_Warnings;

   --------------------------
   -- Validity_Check_Range --
   --------------------------

   procedure Validity_Check_Range
     (N          : Node_Id;
      Related_Id : Entity_Id := Empty) is
   begin
      if Validity_Checks_On and Validity_Check_Operands then
         if Nkind (N) = N_Range then
            Ensure_Valid
              (Expr          => Low_Bound (N),
               Related_Id    => Related_Id,
               Is_Low_Bound  => True);

            Ensure_Valid
              (Expr          => High_Bound (N),
               Related_Id    => Related_Id,
               Is_High_Bound => True);
         end if;
      end if;
   end Validity_Check_Range;

end Checks;
