------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ E V A L                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2023, 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 Aspects;        use Aspects;
with Atree;          use Atree;
with Checks;         use Checks;
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 Errout;         use Errout;
with Eval_Fat;       use Eval_Fat;
with Exp_Util;       use Exp_Util;
with Freeze;         use Freeze;
with Lib;            use Lib;
with Namet;          use Namet;
with Nmake;          use Nmake;
with Nlists;         use Nlists;
with Opt;            use Opt;
with Par_SCO;        use Par_SCO;
with Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_Aggr;       use Sem_Aggr;
with Sem_Aux;        use Sem_Aux;
with Sem_Cat;        use Sem_Cat;
with Sem_Ch3;        use Sem_Ch3;
with Sem_Ch6;        use Sem_Ch6;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Elab;       use Sem_Elab;
with Sem_Res;        use Sem_Res;
with Sem_Util;       use Sem_Util;
with Sem_Type;       use Sem_Type;
with Sem_Warn;       use Sem_Warn;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Snames;         use Snames;
with Stand;          use Stand;
with Stringt;        use Stringt;
with Tbuild;         use Tbuild;
with Warnsw;         use Warnsw;

package body Sem_Eval is

   -----------------------------------------
   -- Handling of Compile Time Evaluation --
   -----------------------------------------

   --  The compile time evaluation of expressions is distributed over several
   --  Eval_xxx procedures. These procedures are called immediately after
   --  a subexpression is resolved and is therefore accomplished in a bottom
   --  up fashion. The flags are synthesized using the following approach.

   --    Is_Static_Expression is determined by following the rules in
   --    RM-4.9. This involves testing the Is_Static_Expression flag of
   --    the operands in many cases.

   --    Raises_Constraint_Error is usually set if any of the operands have
   --    the flag set or if an attempt to compute the value of the current
   --    expression results in Constraint_Error.

   --  The general approach is as follows. First compute Is_Static_Expression.
   --  If the node is not static, then the flag is left off in the node and
   --  we are all done. Otherwise for a static node, we test if any of the
   --  operands will raise Constraint_Error, and if so, propagate the flag
   --  Raises_Constraint_Error to the result node and we are done (since the
   --  error was already posted at a lower level).

   --  For the case of a static node whose operands do not raise constraint
   --  error, we attempt to evaluate the node. If this evaluation succeeds,
   --  then the node is replaced by the result of this computation. If the
   --  evaluation raises Constraint_Error, then we rewrite the node with
   --  Apply_Compile_Time_Constraint_Error to raise the exception and also
   --  to post appropriate error messages.

   ----------------
   -- Local Data --
   ----------------

   type Bits is array (Nat range <>) of Boolean;
   --  Used to convert unsigned (modular) values for folding logical ops

   --  The following declarations are used to maintain a cache of nodes that
   --  have compile-time-known values. The cache is maintained only for
   --  discrete types (the most common case), and is populated by calls to
   --  Compile_Time_Known_Value and Expr_Value, but only used by Expr_Value
   --  since it is possible for the status to change (in particular it is
   --  possible for a node to get replaced by a Constraint_Error node).

   CV_Bits : constant := 5;
   --  Number of low order bits of Node_Id value used to reference entries
   --  in the cache table.

   CV_Cache_Size : constant Nat := 2 ** CV_Bits;
   --  Size of cache for compile time values

   subtype CV_Range is Nat range 0 .. CV_Cache_Size;

   type CV_Entry is record
      N : Node_Id'Base;
      --  We use 'Base here, in case we want to add a predicate to Node_Id
      V : Uint;
   end record;

   type Match_Result is (Match, No_Match, Non_Static);
   --  Result returned from functions that test for a matching result. If the
   --  operands are not OK_Static then Non_Static will be returned. Otherwise
   --  Match/No_Match is returned depending on whether the match succeeds.

   type CV_Cache_Array is array (CV_Range) of CV_Entry;

   CV_Cache : CV_Cache_Array;
   --  This is the actual cache, with entries consisting of node/value pairs,
   --  and the impossible value Node_High_Bound used for unset entries.

   type Range_Membership is (In_Range, Out_Of_Range, Unknown);
   --  Range membership may either be statically known to be in range or out
   --  of range, or not statically known. Used for Test_In_Range below.

   Checking_For_Potentially_Static_Expression : Boolean := False;
   --  Global flag that is set True during Analyze_Static_Expression_Function
   --  in order to verify that the result expression of a static expression
   --  function is a potentially static function (see RM2022 6.8(5.3)).

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

   procedure Check_Non_Static_Context_For_Overflow
     (N      : Node_Id;
      Stat   : Boolean;
      Result : Uint);
   --  For a signed integer type, check non-static overflow in Result when
   --  Stat is False. This applies also inside inlined code, where the static
   --  property may be an effect of the inlining, which should not be allowed
   --  to remove run-time checks (whether during compilation, or even more
   --  crucially in the special inlining-for-proof in GNATprove mode).

   function Choice_Matches
     (Expr   : Node_Id;
      Choice : Node_Id) return Match_Result;
   --  Determines whether given value Expr matches the given Choice. The Expr
   --  can be of discrete, real, or string type and must be a compile time
   --  known value (it is an error to make the call if these conditions are
   --  not met). The choice can be a range, subtype name, subtype indication,
   --  or expression. The returned result is Non_Static if Choice is not
   --  OK_Static, otherwise either Match or No_Match is returned depending
   --  on whether Choice matches Expr. This is used for case expression
   --  alternatives, and also for membership tests. In each case, more
   --  possibilities are tested than the syntax allows (e.g. membership allows
   --  subtype indications and non-discrete types, and case allows an OTHERS
   --  choice), but it does not matter, since we have already done a full
   --  semantic and syntax check of the construct, so the extra possibilities
   --  just will not arise for correct expressions.
   --
   --  Note: if Choice_Matches finds that a choice raises Constraint_Error, e.g
   --  a reference to a type, one of whose bounds raises Constraint_Error, then
   --  it also sets the Raises_Constraint_Error flag on the Choice itself.

   function Choices_Match
     (Expr    : Node_Id;
      Choices : List_Id) return Match_Result;
   --  This function applies Choice_Matches to each element of Choices. If the
   --  result is No_Match, then it continues and checks the next element. If
   --  the result is Match or Non_Static, this result is immediately given
   --  as the result without checking the rest of the list. Expr can be of
   --  discrete, real, or string type and must be a compile-time-known value
   --  (it is an error to make the call if these conditions are not met).

   procedure Eval_Intrinsic_Call (N : Node_Id; E : Entity_Id);
   --  Evaluate a call N to an intrinsic subprogram E.

   function Find_Universal_Operator_Type (N : Node_Id) return Entity_Id;
   --  Check whether an arithmetic operation with universal operands which is a
   --  rewritten function call with an explicit scope indication is ambiguous:
   --  P."+" (1, 2) will be ambiguous if there is more than one visible numeric
   --  type declared in P and the context does not impose a type on the result
   --  (e.g. in the expression of a type conversion). If ambiguous, emit an
   --  error and return Empty, else return the result type of the operator.

   procedure Fold_Dummy (N : Node_Id; Typ : Entity_Id);
   --  Rewrite N as a constant dummy value in the relevant type if possible.

   procedure Fold_Shift
     (N          : Node_Id;
      Left       : Node_Id;
      Right      : Node_Id;
      Op         : Node_Kind;
      Static     : Boolean := False;
      Check_Elab : Boolean := False);
   --  Rewrite N as the result of evaluating Left <shift op> Right if possible.
   --  Op represents the shift operation.
   --  Static indicates whether the resulting node should be marked static.
   --  Check_Elab indicates whether checks for elaboration calls should be
   --  inserted when relevant.

   function From_Bits (B : Bits; T : Entity_Id) return Uint;
   --  Converts a bit string of length B'Length to a Uint value to be used for
   --  a target of type T, which is a modular type. This procedure includes the
   --  necessary reduction by the modulus in the case of a nonbinary modulus
   --  (for a binary modulus, the bit string is the right length any way so all
   --  is well).

   function Get_String_Val (N : Node_Id) return Node_Id;
   --  Given a tree node for a folded string or character value, returns the
   --  corresponding string literal or character literal (one of the two must
   --  be available, or the operand would not have been marked as foldable in
   --  the earlier analysis of the operation).

   function Is_OK_Static_Choice (Choice : Node_Id) return Boolean;
   --  Given a choice (from a case expression or membership test), returns
   --  True if the choice is static and does not raise a Constraint_Error.

   function Is_OK_Static_Choice_List (Choices : List_Id) return Boolean;
   --  Given a choice list (from a case expression or membership test), return
   --  True if all choices are static in the sense of Is_OK_Static_Choice.

   function Is_Static_Choice (Choice : Node_Id) return Boolean;
   --  Given a choice (from a case expression or membership test), returns
   --  True if the choice is static. No test is made for raising of constraint
   --  error, so this function is used only for legality tests.

   function Is_Static_Choice_List (Choices : List_Id) return Boolean;
   --  Given a choice list (from a case expression or membership test), return
   --  True if all choices are static in the sense of Is_Static_Choice.

   function Is_Static_Range (N : Node_Id) return Boolean;
   --  Determine if range is static, as defined in RM 4.9(26). The only allowed
   --  argument is an N_Range node (but note that the semantic analysis of
   --  equivalent range attribute references already turned them into the
   --  equivalent range). This differs from Is_OK_Static_Range (which is what
   --  must be used by clients) in that it does not care whether the bounds
   --  raise Constraint_Error or not. Used for checking whether expressions are
   --  static in the 4.9 sense (without worrying about exceptions).

   function OK_Bits (N : Node_Id; Bits : Uint) return Boolean;
   --  Bits represents the number of bits in an integer value to be computed
   --  (but the value has not been computed yet). If this value in Bits is
   --  reasonable, a result of True is returned, with the implication that the
   --  caller should go ahead and complete the calculation. If the value in
   --  Bits is unreasonably large, then an error is posted on node N, and
   --  False is returned (and the caller skips the proposed calculation).

   procedure Out_Of_Range (N : Node_Id);
   --  This procedure is called if it is determined that node N, which appears
   --  in a non-static context, is a compile-time-known value which is outside
   --  its range, i.e. the range of Etype. This is used in contexts where
   --  this is an illegality if N is static, and should generate a warning
   --  otherwise.

   function Real_Or_String_Static_Predicate_Matches
     (Val : Node_Id;
      Typ : Entity_Id) return Boolean;
   --  This is the function used to evaluate real or string static predicates.
   --  Val is an unanalyzed N_Real_Literal or N_String_Literal node, which
   --  represents the value to be tested against the predicate. Typ is the
   --  type with the predicate, from which the predicate expression can be
   --  extracted. The result returned is True if the given value satisfies
   --  the predicate.

   procedure Rewrite_In_Raise_CE (N : Node_Id; Exp : Node_Id);
   --  N and Exp are nodes representing an expression, Exp is known to raise
   --  CE. N is rewritten in term of Exp in the optimal way.

   function String_Type_Len (Stype : Entity_Id) return Uint;
   --  Given a string type, determines the length of the index type, or, if
   --  this index type is non-static, the length of the base type of this index
   --  type. Note that if the string type is itself static, then the index type
   --  is static, so the second case applies only if the string type passed is
   --  non-static.

   function Test (Cond : Boolean) return Uint;
   pragma Inline (Test);
   --  This function simply returns the appropriate Boolean'Pos value
   --  corresponding to the value of Cond as a universal integer. It is
   --  used for producing the result of the static evaluation of the
   --  logical operators

   procedure Test_Expression_Is_Foldable
     (N    : Node_Id;
      Op1  : Node_Id;
      Stat : out Boolean;
      Fold : out Boolean);
   --  Tests to see if expression N whose single operand is Op1 is foldable,
   --  i.e. the operand value is known at compile time. If the operation is
   --  foldable, then Fold is True on return, and Stat indicates whether the
   --  result is static (i.e. the operand was static). Note that it is quite
   --  possible for Fold to be True, and Stat to be False, since there are
   --  cases in which we know the value of an operand even though it is not
   --  technically static (e.g. the static lower bound of a range whose upper
   --  bound is non-static).
   --
   --  If Stat is set False on return, then Test_Expression_Is_Foldable makes
   --  a call to Check_Non_Static_Context on the operand. If Fold is False on
   --  return, then all processing is complete, and the caller should return,
   --  since there is nothing else to do.
   --
   --  If Stat is set True on return, then Is_Static_Expression is also set
   --  true in node N. There are some cases where this is over-enthusiastic,
   --  e.g. in the two operand case below, for string comparison, the result is
   --  not static even though the two operands are static. In such cases, the
   --  caller must reset the Is_Static_Expression flag in N.
   --
   --  If Fold and Stat are both set to False then this routine performs also
   --  the following extra actions:
   --
   --    If either operand is Any_Type then propagate it to result to prevent
   --    cascaded errors.
   --
   --    If some operand raises Constraint_Error, then replace the node N
   --    with the raise Constraint_Error node. This replacement inherits the
   --    Is_Static_Expression flag from the operands.

   procedure Test_Expression_Is_Foldable
     (N        : Node_Id;
      Op1      : Node_Id;
      Op2      : Node_Id;
      Stat     : out Boolean;
      Fold     : out Boolean;
      CRT_Safe : Boolean := False);
   --  Same processing, except applies to an expression N with two operands
   --  Op1 and Op2. The result is static only if both operands are static. If
   --  CRT_Safe is set True, then CRT_Safe_Compile_Time_Known_Value is used
   --  for the tests that the two operands are known at compile time. See
   --  spec of this routine for further details.

   function Test_In_Range
     (N            : Node_Id;
      Typ          : Entity_Id;
      Assume_Valid : Boolean;
      Fixed_Int    : Boolean;
      Int_Real     : Boolean) return Range_Membership;
   --  Common processing for Is_In_Range and Is_Out_Of_Range: Returns In_Range
   --  or Out_Of_Range if it can be guaranteed at compile time that expression
   --  N is known to be in or out of range of the subtype Typ. If not compile
   --  time known, Unknown is returned. See documentation of Is_In_Range for
   --  complete description of parameters.

   procedure To_Bits (U : Uint; B : out Bits);
   --  Converts a Uint value to a bit string of length B'Length

   -----------------------------------------------
   -- Check_Expression_Against_Static_Predicate --
   -----------------------------------------------

   procedure Check_Expression_Against_Static_Predicate
     (Expr                    : Node_Id;
      Typ                     : Entity_Id;
      Static_Failure_Is_Error : Boolean := False)
   is
   begin
      --  Nothing to do if expression is not known at compile time, or the
      --  type has no static predicate set (will be the case for all non-scalar
      --  types, so no need to make a special test for that).

      if not (Has_Static_Predicate (Typ)
               and then Compile_Time_Known_Value (Expr))
      then
         return;
      end if;

      --  Here we have a static predicate (note that it could have arisen from
      --  an explicitly specified Dynamic_Predicate whose expression met the
      --  rules for being predicate-static). If the expression is known at
      --  compile time and obeys the predicate, then it is static and must be
      --  labeled as such, which matters e.g. for case statements. The original
      --  expression may be a type conversion of a variable with a known value,
      --  which might otherwise not be marked static.

      --  Case of real static predicate

      if Is_Real_Type (Typ) then
         if Real_Or_String_Static_Predicate_Matches
              (Val => Make_Real_Literal (Sloc (Expr), Expr_Value_R (Expr)),
               Typ => Typ)
         then
            Set_Is_Static_Expression (Expr);
            return;
         end if;

      --  Case of string static predicate

      elsif Is_String_Type (Typ) then
         if Real_Or_String_Static_Predicate_Matches
              (Val => Expr_Value_S (Expr), Typ => Typ)
         then
            Set_Is_Static_Expression (Expr);
            return;
         end if;

      --  Case of discrete static predicate

      else
         pragma Assert (Is_Discrete_Type (Typ));

         --  If static predicate matches, nothing to do

         if Choices_Match (Expr, Static_Discrete_Predicate (Typ)) = Match then
            Set_Is_Static_Expression (Expr);
            return;
         end if;
      end if;

      --  Here we know that the predicate will fail

      --  Special case of static expression failing a predicate (other than one
      --  that was explicitly specified with a Dynamic_Predicate aspect). If
      --  the expression comes from a qualified_expression or type_conversion
      --  this is an error (Static_Failure_Is_Error); otherwise we only issue
      --  a warning and the expression is no longer considered static.

      if Is_Static_Expression (Expr)
        and then not Has_Dynamic_Predicate_Aspect (Typ)
        and then not Has_Ghost_Predicate_Aspect (Typ)
      then
         if Static_Failure_Is_Error then
            Error_Msg_NE
              ("static expression fails static predicate check on &",
               Expr, Typ);

         else
            Error_Msg_NE
              ("??static expression fails static predicate check on &",
               Expr, Typ);
            Error_Msg_N
              ("\??expression is no longer considered static", Expr);

            Set_Is_Static_Expression (Expr, False);
         end if;

      --  In all other cases, this is just a warning that a test will fail.
      --  It does not matter if the expression is static or not, or if the
      --  predicate comes from a dynamic predicate aspect or not.

      else
         Error_Msg_NE
           ("??expression fails predicate check on &", Expr, Typ);

         --  Force a check here, which is potentially a redundant check, but
         --  this ensures a check will be done in cases where the expression
         --  is folded, and since this is definitely a failure, extra checks
         --  are OK.

         if Predicate_Enabled (Typ) then
            Insert_Action (Expr,
              Make_Predicate_Check
                (Typ, Duplicate_Subexpr (Expr)), Suppress => All_Checks);
         end if;
      end if;
   end Check_Expression_Against_Static_Predicate;

   ------------------------------
   -- Check_Non_Static_Context --
   ------------------------------

   procedure Check_Non_Static_Context (N : Node_Id) is
      T         : constant Entity_Id := Etype (N);
      Checks_On : constant Boolean   :=
                    not Index_Checks_Suppressed (T)
                      and not Range_Checks_Suppressed (T);

   begin
      --  Ignore cases of non-scalar types, error types, or universal real
      --  types that have no usable bounds.

      if T = Any_Type
        or else not Is_Scalar_Type (T)
        or else T = Universal_Fixed
        or else T = Universal_Real
      then
         return;
      end if;

      --  At this stage we have a scalar type. If we have an expression that
      --  raises CE, then we already issued a warning or error msg so there is
      --  nothing more to be done in this routine.

      if Raises_Constraint_Error (N) then
         return;
      end if;

      --  Now we have a scalar type which is not marked as raising a constraint
      --  error exception. The main purpose of this routine is to deal with
      --  static expressions appearing in a non-static context. That means
      --  that if we do not have a static expression then there is not much
      --  to do. The one case that we deal with here is that if we have a
      --  floating-point value that is out of range, then we post a warning
      --  that an infinity will result.

      if not Is_Static_Expression (N) then
         if Is_Floating_Point_Type (T) then
            if Is_Out_Of_Range (N, Base_Type (T), Assume_Valid => True) then
               Error_Msg_N
                 ("??float value out of range, infinity will be generated", N);

            --  The literal may be the result of constant-folding of a non-
            --  static subexpression of a larger expression (e.g. a conversion
            --  of a non-static variable whose value happens to be known). At
            --  this point we must reduce the value of the subexpression to a
            --  machine number (RM 4.9 (38/2)).

            elsif Nkind (N) = N_Real_Literal
              and then Nkind (Parent (N)) in N_Subexpr
            then
               Rewrite (N, New_Copy (N));
               Set_Realval (N, Machine_Number (Base_Type (T), Realval (N), N));
               Set_Is_Machine_Number (N);
            end if;
         end if;

         return;
      end if;

      --  Here we have the case of outer level static expression of scalar
      --  type, where the processing of this procedure is needed.

      --  For real types, this is where we convert the value to a machine
      --  number (see RM 4.9(38)). Also see ACVC test C490001. We should only
      --  need to do this if the parent is a constant declaration, since in
      --  other cases, gigi should do the necessary conversion correctly, but
      --  experimentation shows that this is not the case on all machines, in
      --  particular if we do not convert all literals to machine values in
      --  non-static contexts, then ACVC test C490001 fails on Sparc/Solaris
      --  and SGI/Irix.

      --  This conversion is always done by GNATprove on real literals in
      --  non-static expressions, by calling Check_Non_Static_Context from
      --  gnat2why, as GNATprove cannot do the conversion later contrary
      --  to gigi. The frontend computes the information about which
      --  expressions are static, which is used by gnat2why to call
      --  Check_Non_Static_Context on exactly those real literals that are
      --  not subexpressions of static expressions.

      if Nkind (N) = N_Real_Literal
        and then not Is_Machine_Number (N)
        and then not Is_Generic_Type (Etype (N))
        and then Etype (N) /= Universal_Real
      then
         --  Check that value is in bounds before converting to machine
         --  number, so as not to lose case where value overflows in the
         --  least significant bit or less. See B490001.

         if Is_Out_Of_Range (N, Base_Type (T), Assume_Valid => True) then
            Out_Of_Range (N);
            return;
         end if;

         --  Note: we have to copy the node, to avoid problems with conformance
         --  of very similar numbers (see ACVC tests B4A010C and B63103A).

         Rewrite (N, New_Copy (N));

         if not Is_Floating_Point_Type (T) then
            Set_Realval
              (N, Corresponding_Integer_Value (N) * Small_Value (T));

         elsif not UR_Is_Zero (Realval (N)) then
            Set_Realval (N, Machine_Number (Base_Type (T), Realval (N), N));
            Set_Is_Machine_Number (N);
         end if;

      end if;

      --  Check for out of range universal integer. This is a non-static
      --  context, so the integer value must be in range of the runtime
      --  representation of universal integers.

      --  We do this only within an expression, because that is the only
      --  case in which non-static universal integer values can occur, and
      --  furthermore, Check_Non_Static_Context is currently (incorrectly???)
      --  called in contexts like the expression of a number declaration where
      --  we certainly want to allow out of range values.

      --  We inhibit the warning when expansion is disabled, because the
      --  preanalysis of a range of a 64-bit modular type may appear to
      --  violate the constraint on non-static Universal_Integer. If there
      --  is a true overflow it will be diagnosed during full analysis.

      if Etype (N) = Universal_Integer
        and then Nkind (N) = N_Integer_Literal
        and then Nkind (Parent (N)) in N_Subexpr
        and then Expander_Active
        and then
          (Intval (N) < Expr_Value (Type_Low_Bound (Universal_Integer))
             or else
           Intval (N) > Expr_Value (Type_High_Bound (Universal_Integer)))
      then
         Apply_Compile_Time_Constraint_Error
           (N, "non-static universal integer value out of range<<",
            CE_Range_Check_Failed);

      --  Check out of range of base type

      elsif Is_Out_Of_Range (N, Base_Type (T), Assume_Valid => True) then
         Out_Of_Range (N);

      --  Give a warning or error on the value outside the subtype. A warning
      --  is omitted if the expression appears in a range that could be null
      --  (warnings are handled elsewhere for this case).

      elsif T /= Base_Type (T) and then Nkind (Parent (N)) /= N_Range then
         if Is_In_Range (N, T, Assume_Valid => True) then
            null;

         elsif Is_Out_Of_Range (N, T, Assume_Valid => True) then
            --  Ignore out of range values for System.Priority in CodePeer
            --  mode since the actual target compiler may provide a wider
            --  range.

            if CodePeer_Mode and then Is_RTE (T, RE_Priority) then
               Set_Do_Range_Check (N, False);

            --  Determine if the out-of-range violation constitutes a warning
            --  or an error based on context, according to RM 4.9 (34/3).

            elsif Nkind (Original_Node (N)) in
                    N_Type_Conversion | N_Qualified_Expression
              and then Comes_From_Source (Original_Node (N))
            then
               Apply_Compile_Time_Constraint_Error
                 (N, "value not in range of}", CE_Range_Check_Failed);
            else
               Apply_Compile_Time_Constraint_Error
                 (N, "value not in range of}<<", CE_Range_Check_Failed);
            end if;

         elsif Checks_On then
            Enable_Range_Check (N);

         else
            Set_Do_Range_Check (N, False);
         end if;
      end if;
   end Check_Non_Static_Context;

   -------------------------------------------
   -- Check_Non_Static_Context_For_Overflow --
   -------------------------------------------

   procedure Check_Non_Static_Context_For_Overflow
     (N      : Node_Id;
      Stat   : Boolean;
      Result : Uint)
   is
   begin
      if (not Stat or else In_Inlined_Body)
        and then Is_Signed_Integer_Type (Etype (N))
      then
         declare
            BT : constant Entity_Id := Base_Type (Etype (N));
            Lo : constant Uint := Expr_Value (Type_Low_Bound (BT));
            Hi : constant Uint := Expr_Value (Type_High_Bound (BT));
         begin
            if Result < Lo or else Result > Hi then
               Apply_Compile_Time_Constraint_Error
                 (N, "value not in range of }??",
                  CE_Overflow_Check_Failed,
                  Ent => BT);
            end if;
         end;
      end if;
   end Check_Non_Static_Context_For_Overflow;

   ---------------------------------
   -- Check_String_Literal_Length --
   ---------------------------------

   procedure Check_String_Literal_Length (N : Node_Id; Ttype : Entity_Id) is
   begin
      if not Raises_Constraint_Error (N) and then Is_Constrained (Ttype) then
         if UI_From_Int (String_Length (Strval (N))) /= String_Type_Len (Ttype)
         then
            Apply_Compile_Time_Constraint_Error
              (N, "string length wrong for}??",
               CE_Length_Check_Failed,
               Ent => Ttype,
               Typ => Ttype);
         end if;
      end if;
   end Check_String_Literal_Length;

   --------------------------------------------
   -- Checking_Potentially_Static_Expression --
   --------------------------------------------

   function Checking_Potentially_Static_Expression return Boolean is
   begin
      return Checking_For_Potentially_Static_Expression;
   end Checking_Potentially_Static_Expression;

   --------------------
   -- Choice_Matches --
   --------------------

   function Choice_Matches
     (Expr   : Node_Id;
      Choice : Node_Id) return Match_Result
   is
      Etyp : constant Entity_Id := Etype (Expr);
      Val  : Uint;
      ValR : Ureal;
      ValS : Node_Id;

   begin
      pragma Assert (Compile_Time_Known_Value (Expr));
      pragma Assert (Is_Scalar_Type (Etyp) or else Is_String_Type (Etyp));

      if not Is_OK_Static_Choice (Choice) then
         Set_Raises_Constraint_Error (Choice);
         return Non_Static;

      --  When the choice denotes a subtype with a static predictate, check the
      --  expression against the predicate values. Different procedures apply
      --  to discrete and non-discrete types.

      elsif (Nkind (Choice) = N_Subtype_Indication
              or else (Is_Entity_Name (Choice)
                        and then Is_Type (Entity (Choice))))
        and then Has_Predicates (Etype (Choice))
        and then Has_Static_Predicate (Etype (Choice))
      then
         if Is_Discrete_Type (Etype (Choice)) then
            return
              Choices_Match
                (Expr, Static_Discrete_Predicate (Etype (Choice)));

         elsif Real_Or_String_Static_Predicate_Matches (Expr, Etype (Choice))
         then
            return Match;

         else
            return No_Match;
         end if;

      --  Discrete type case only

      elsif Is_Discrete_Type (Etyp) then
         Val := Expr_Value (Expr);

         if Nkind (Choice) = N_Range then
            if Val >= Expr_Value (Low_Bound (Choice))
                 and then
               Val <= Expr_Value (High_Bound (Choice))
            then
               return Match;
            else
               return No_Match;
            end if;

         elsif Nkind (Choice) = N_Subtype_Indication
           or else (Is_Entity_Name (Choice) and then Is_Type (Entity (Choice)))
         then
            if Val >= Expr_Value (Type_Low_Bound  (Etype (Choice)))
                 and then
               Val <= Expr_Value (Type_High_Bound (Etype (Choice)))
            then
               return Match;
            else
               return No_Match;
            end if;

         elsif Nkind (Choice) = N_Others_Choice then
            return Match;

         else
            if Val = Expr_Value (Choice) then
               return Match;
            else
               return No_Match;
            end if;
         end if;

      --  Real type case

      elsif Is_Real_Type (Etyp) then
         ValR := Expr_Value_R (Expr);

         if Nkind (Choice) = N_Range then
            if ValR >= Expr_Value_R (Low_Bound  (Choice))
                 and then
               ValR <= Expr_Value_R (High_Bound (Choice))
            then
               return Match;
            else
               return No_Match;
            end if;

         elsif Nkind (Choice) = N_Subtype_Indication
           or else (Is_Entity_Name (Choice) and then Is_Type (Entity (Choice)))
         then
            if ValR >= Expr_Value_R (Type_Low_Bound  (Etype (Choice)))
                 and then
               ValR <= Expr_Value_R (Type_High_Bound (Etype (Choice)))
            then
               return Match;
            else
               return No_Match;
            end if;

         else
            if ValR = Expr_Value_R (Choice) then
               return Match;
            else
               return No_Match;
            end if;
         end if;

      --  String type cases

      else
         pragma Assert (Is_String_Type (Etyp));
         ValS := Expr_Value_S (Expr);

         if Nkind (Choice) = N_Subtype_Indication
           or else (Is_Entity_Name (Choice) and then Is_Type (Entity (Choice)))
         then
            if not Is_Constrained (Etype (Choice)) then
               return Match;

            else
               declare
                  Typlen : constant Uint :=
                             String_Type_Len (Etype (Choice));
                  Strlen : constant Uint :=
                             UI_From_Int (String_Length (Strval (ValS)));
               begin
                  if Typlen = Strlen then
                     return Match;
                  else
                     return No_Match;
                  end if;
               end;
            end if;

         else
            if String_Equal (Strval (ValS), Strval (Expr_Value_S (Choice)))
            then
               return Match;
            else
               return No_Match;
            end if;
         end if;
      end if;
   end Choice_Matches;

   -------------------
   -- Choices_Match --
   -------------------

   function Choices_Match
     (Expr    : Node_Id;
      Choices : List_Id) return Match_Result
   is
      Choice : Node_Id;
      Result : Match_Result;

   begin
      Choice := First (Choices);
      while Present (Choice) loop
         Result := Choice_Matches (Expr, Choice);

         if Result /= No_Match then
            return Result;
         end if;

         Next (Choice);
      end loop;

      return No_Match;
   end Choices_Match;

   --------------------------
   -- Compile_Time_Compare --
   --------------------------

   function Compile_Time_Compare
     (L, R         : Node_Id;
      Assume_Valid : Boolean) return Compare_Result
   is
      Discard : aliased Uint;
   begin
      return Compile_Time_Compare (L, R, Discard'Access, Assume_Valid);
   end Compile_Time_Compare;

   function Compile_Time_Compare
     (L, R         : Node_Id;
      Diff         : access Uint;
      Assume_Valid : Boolean;
      Rec          : Boolean := False) return Compare_Result
   is
      Ltyp : Entity_Id := Etype (L);
      Rtyp : Entity_Id := Etype (R);

      Discard : aliased Uint;

      procedure Compare_Decompose
        (N : Node_Id;
         R : out Node_Id;
         V : out Uint);
      --  This procedure decomposes the node N into an expression node and a
      --  signed offset, so that the value of N is equal to the value of R plus
      --  the value V (which may be negative). If no such decomposition is
      --  possible, then on return R is a copy of N, and V is set to zero.

      function Compare_Fixup (N : Node_Id) return Node_Id;
      --  This function deals with replacing 'Last and 'First references with
      --  their corresponding type bounds, which we then can compare. The
      --  argument is the original node, the result is the identity, unless we
      --  have a 'Last/'First reference in which case the value returned is the
      --  appropriate type bound.

      function Is_Known_Valid_Operand (Opnd : Node_Id) return Boolean;
      --  Even if the context does not assume that values are valid, some
      --  simple cases can be recognized.

      function Is_Same_Value (L, R : Node_Id) return Boolean;
      --  Returns True iff L and R represent expressions that definitely have
      --  identical (but not necessarily compile-time-known) values Indeed the
      --  caller is expected to have already dealt with the cases of compile
      --  time known values, so these are not tested here.

      -----------------------
      -- Compare_Decompose --
      -----------------------

      procedure Compare_Decompose
        (N : Node_Id;
         R : out Node_Id;
         V : out Uint)
      is
      begin
         if Nkind (N) = N_Op_Add
           and then Nkind (Right_Opnd (N)) = N_Integer_Literal
         then
            R := Left_Opnd (N);
            V := Intval (Right_Opnd (N));
            return;

         elsif Nkind (N) = N_Op_Subtract
           and then Nkind (Right_Opnd (N)) = N_Integer_Literal
         then
            R := Left_Opnd (N);
            V := UI_Negate (Intval (Right_Opnd (N)));
            return;

         elsif Nkind (N) = N_Attribute_Reference then
            if Attribute_Name (N) = Name_Succ then
               R := First (Expressions (N));
               V := Uint_1;
               return;

            elsif Attribute_Name (N) = Name_Pred then
               R := First (Expressions (N));
               V := Uint_Minus_1;
               return;
            end if;
         end if;

         R := N;
         V := Uint_0;
      end Compare_Decompose;

      -------------------
      -- Compare_Fixup --
      -------------------

      function Compare_Fixup (N : Node_Id) return Node_Id is
         Indx : Node_Id;
         Xtyp : Entity_Id;
         Subs : Nat;

      begin
         --  Fixup only required for First/Last attribute reference

         if Nkind (N) = N_Attribute_Reference
           and then Attribute_Name (N) in Name_First | Name_Last
         then
            Xtyp := Etype (Prefix (N));

            --  If we have no type, then just abandon the attempt to do
            --  a fixup, this is probably the result of some other error.

            if No (Xtyp) then
               return N;
            end if;

            --  Dereference an access type

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

            --  If we don't have an array type at this stage, something is
            --  peculiar, e.g. another error, and we abandon the attempt at
            --  a fixup.

            if not Is_Array_Type (Xtyp) then
               return N;
            end if;

            --  Ignore unconstrained array, since bounds are not meaningful

            if not Is_Constrained (Xtyp) then
               return N;
            end if;

            if Ekind (Xtyp) = E_String_Literal_Subtype then
               if Attribute_Name (N) = Name_First then
                  return String_Literal_Low_Bound (Xtyp);
               else
                  return
                    Make_Integer_Literal (Sloc (N),
                      Intval => Intval (String_Literal_Low_Bound (Xtyp)) +
                                          String_Literal_Length (Xtyp));
               end if;
            end if;

            --  Find correct index type

            Indx := First_Index (Xtyp);

            if Present (Expressions (N)) then
               Subs := UI_To_Int (Expr_Value (First (Expressions (N))));

               for J in 2 .. Subs loop
                  Next_Index (Indx);
               end loop;
            end if;

            Xtyp := Etype (Indx);

            if Attribute_Name (N) = Name_First then
               return Type_Low_Bound (Xtyp);
            else
               return Type_High_Bound (Xtyp);
            end if;
         end if;

         return N;
      end Compare_Fixup;

      ----------------------------
      -- Is_Known_Valid_Operand --
      ----------------------------

      function Is_Known_Valid_Operand (Opnd : Node_Id) return Boolean is
      begin
         return (Is_Entity_Name (Opnd)
                  and then
                    (Is_Known_Valid (Entity (Opnd))
                      or else Ekind (Entity (Opnd)) = E_In_Parameter
                      or else
                        (Is_Object (Entity (Opnd))
                          and then Present (Current_Value (Entity (Opnd))))))
           or else Is_OK_Static_Expression (Opnd);
      end Is_Known_Valid_Operand;

      -------------------
      -- Is_Same_Value --
      -------------------

      function Is_Same_Value (L, R : Node_Id) return Boolean is
         Lf : constant Node_Id := Compare_Fixup (L);
         Rf : constant Node_Id := Compare_Fixup (R);

         function Is_Rewritten_Loop_Entry (N : Node_Id) return Boolean;
         --  An attribute reference to Loop_Entry may have been rewritten into
         --  its prefix as a way to avoid generating a constant for that
         --  attribute when the corresponding pragma is ignored. These nodes
         --  should be ignored when deciding if they can be equal to one
         --  another.

         function Is_Same_Subscript (L, R : List_Id) return Boolean;
         --  L, R are the Expressions values from two attribute nodes for First
         --  or Last attributes. Either may be set to No_List if no expressions
         --  are present (indicating subscript 1). The result is True if both
         --  expressions represent the same subscript (note one case is where
         --  one subscript is missing and the other is explicitly set to 1).

         -----------------------------
         -- Is_Rewritten_Loop_Entry --
         -----------------------------

         function Is_Rewritten_Loop_Entry (N : Node_Id) return Boolean is
            Orig_N : constant Node_Id := Original_Node (N);
         begin
            return Orig_N /= N
              and then Nkind (Orig_N) = N_Attribute_Reference
              and then Get_Attribute_Id (Attribute_Name (Orig_N)) =
                Attribute_Loop_Entry;
         end Is_Rewritten_Loop_Entry;

         -----------------------
         -- Is_Same_Subscript --
         -----------------------

         function Is_Same_Subscript (L, R : List_Id) return Boolean is
         begin
            if L = No_List then
               if R = No_List then
                  return True;
               else
                  return Expr_Value (First (R)) = Uint_1;
               end if;

            else
               if R = No_List then
                  return Expr_Value (First (L)) = Uint_1;
               else
                  return Expr_Value (First (L)) = Expr_Value (First (R));
               end if;
            end if;
         end Is_Same_Subscript;

      --  Start of processing for Is_Same_Value

      begin
         --  Loop_Entry nodes rewritten into their prefix inside ignored
         --  pragmas should never lead to a decision of equality.

         if Is_Rewritten_Loop_Entry (Lf)
           or else Is_Rewritten_Loop_Entry (Rf)
         then
            return False;

         --  Values are the same if they refer to the same entity and the
         --  entity is nonvolatile.

         elsif Nkind (Lf) in N_Identifier | N_Expanded_Name
           and then Nkind (Rf) in N_Identifier | N_Expanded_Name
           and then Entity (Lf) = Entity (Rf)

           --  If the entity is a discriminant, the two expressions may be
           --  bounds of components of objects of the same discriminated type.
           --  The values of the discriminants are not static, and therefore
           --  the result is unknown.

           and then Ekind (Entity (Lf)) /= E_Discriminant
           and then Present (Entity (Lf))

           --  This does not however apply to Float types, since we may have
           --  two NaN values and they should never compare equal.

           and then not Is_Floating_Point_Type (Etype (L))
           and then not Is_Volatile_Reference (L)
           and then not Is_Volatile_Reference (R)
         then
            return True;

         --  Or if they are compile-time-known and identical

         elsif Compile_Time_Known_Value (Lf)
                 and then
               Compile_Time_Known_Value (Rf)
           and then Expr_Value (Lf) = Expr_Value (Rf)
         then
            return True;

         --  False if Nkind of the two nodes is different for remaining cases

         elsif Nkind (Lf) /= Nkind (Rf) then
            return False;

         --  True if both 'First or 'Last values applying to the same entity
         --  (first and last don't change even if value does). Note that we
         --  need this even with the calls to Compare_Fixup, to handle the
         --  case of unconstrained array attributes where Compare_Fixup
         --  cannot find useful bounds.

         elsif Nkind (Lf) = N_Attribute_Reference
           and then Attribute_Name (Lf) = Attribute_Name (Rf)
           and then Attribute_Name (Lf) in Name_First | Name_Last
           and then Nkind (Prefix (Lf)) in N_Identifier | N_Expanded_Name
           and then Nkind (Prefix (Rf)) in N_Identifier | N_Expanded_Name
           and then Entity (Prefix (Lf)) = Entity (Prefix (Rf))
           and then Is_Same_Subscript (Expressions (Lf), Expressions (Rf))
         then
            return True;

         --  True if the same selected component from the same record

         elsif Nkind (Lf) = N_Selected_Component
           and then Selector_Name (Lf) = Selector_Name (Rf)
           and then Is_Same_Value (Prefix (Lf), Prefix (Rf))
         then
            return True;

         --  True if the same unary operator applied to the same operand

         elsif Nkind (Lf) in N_Unary_Op
           and then Is_Same_Value (Right_Opnd (Lf), Right_Opnd (Rf))
         then
            return True;

         --  True if the same binary operator applied to the same operands

         elsif Nkind (Lf) in N_Binary_Op
           and then Is_Same_Value (Left_Opnd  (Lf), Left_Opnd  (Rf))
           and then Is_Same_Value (Right_Opnd (Lf), Right_Opnd (Rf))
         then
            return True;

         --  All other cases, we can't tell, so return False

         else
            return False;
         end if;
      end Is_Same_Value;

   --  Start of processing for Compile_Time_Compare

   begin
      Diff.all := No_Uint;

      --  In preanalysis mode, always return Unknown unless the expression
      --  is static. It is too early to be thinking we know the result of a
      --  comparison, save that judgment for the full analysis. This is
      --  particularly important in the case of pre and postconditions, which
      --  otherwise can be prematurely collapsed into having True or False
      --  conditions when this is inappropriate.

      if not (Full_Analysis
               or else (Is_OK_Static_Expression (L)
                          and then
                        Is_OK_Static_Expression (R)))
      then
         return Unknown;
      end if;

      --  If either operand could raise Constraint_Error, then we cannot
      --  know the result at compile time (since CE may be raised).

      if not (Cannot_Raise_Constraint_Error (L)
                and then
              Cannot_Raise_Constraint_Error (R))
      then
         return Unknown;
      end if;

      --  Identical operands are most certainly equal

      if L = R then
         return EQ;
      end if;

      --  If expressions have no types, then do not attempt to determine if
      --  they are the same, since something funny is going on. One case in
      --  which this happens is during generic template analysis, when bounds
      --  are not fully analyzed.

      if No (Ltyp) or else No (Rtyp) then
         return Unknown;
      end if;

      --  These get reset to the base type for the case of entities where
      --  Is_Known_Valid is not set. This takes care of handling possible
      --  invalid representations using the value of the base type, in
      --  accordance with RM 13.9.1(10).

      Ltyp := Underlying_Type (Ltyp);
      Rtyp := Underlying_Type (Rtyp);

      --  Same rationale as above, but for Underlying_Type instead of Etype

      if No (Ltyp) or else No (Rtyp) then
         return Unknown;
      end if;

      --  We do not attempt comparisons for packed arrays represented as
      --  modular types, where the semantics of comparison is quite different.

      if Is_Packed_Array_Impl_Type (Ltyp)
        and then Is_Modular_Integer_Type (Ltyp)
      then
         return Unknown;

      --  For access types, the only time we know the result at compile time
      --  (apart from identical operands, which we handled already) is if we
      --  know one operand is null and the other is not, or both operands are
      --  known null.

      elsif Is_Access_Type (Ltyp) then
         if Known_Null (L) then
            if Known_Null (R) then
               return EQ;
            elsif Known_Non_Null (R) then
               return NE;
            else
               return Unknown;
            end if;

         elsif Known_Non_Null (L) and then Known_Null (R) then
            return NE;

         else
            return Unknown;
         end if;

      --  Case where comparison involves two compile-time-known values

      elsif Compile_Time_Known_Value (L)
              and then
            Compile_Time_Known_Value (R)
      then
         --  For the floating-point case, we have to be a little careful, since
         --  at compile time we are dealing with universal exact values, but at
         --  runtime, these will be in non-exact target form. That's why the
         --  returned results are LE and GE below instead of LT and GT.

         if Is_Floating_Point_Type (Ltyp)
              or else
            Is_Floating_Point_Type (Rtyp)
         then
            declare
               Lo : constant Ureal := Expr_Value_R (L);
               Hi : constant Ureal := Expr_Value_R (R);
            begin
               if Lo < Hi then
                  return LE;
               elsif Lo = Hi then
                  return EQ;
               else
                  return GE;
               end if;
            end;

         --  For string types, we have two string literals and we proceed to
         --  compare them using the Ada style dictionary string comparison.

         elsif not Is_Scalar_Type (Ltyp) then
            declare
               Lstring : constant String_Id := Strval (Expr_Value_S (L));
               Rstring : constant String_Id := Strval (Expr_Value_S (R));
               Llen    : constant Nat       := String_Length (Lstring);
               Rlen    : constant Nat       := String_Length (Rstring);

            begin
               for J in 1 .. Nat'Min (Llen, Rlen) loop
                  declare
                     LC : constant Char_Code := Get_String_Char (Lstring, J);
                     RC : constant Char_Code := Get_String_Char (Rstring, J);
                  begin
                     if LC < RC then
                        return LT;
                     elsif LC > RC then
                        return GT;
                     end if;
                  end;
               end loop;

               if Llen < Rlen then
                  return LT;
               elsif Llen > Rlen then
                  return GT;
               else
                  return EQ;
               end if;
            end;

         --  For remaining scalar cases we know exactly (note that this does
         --  include the fixed-point case, where we know the run time integer
         --  values now).

         else
            declare
               Lo : constant Uint := Expr_Value (L);
               Hi : constant Uint := Expr_Value (R);
            begin
               if Lo < Hi then
                  Diff.all := Hi - Lo;
                  return LT;
               elsif Lo = Hi then
                  return EQ;
               else
                  Diff.all := Lo - Hi;
                  return GT;
               end if;
            end;
         end if;

      --  Cases where at least one operand is not known at compile time

      else
         --  Remaining checks apply only for discrete types

         if not Is_Discrete_Type (Ltyp)
              or else
            not Is_Discrete_Type (Rtyp)
         then
            return Unknown;
         end if;

         --  Defend against generic types, or actually any expressions that
         --  contain a reference to a generic type from within a generic
         --  template. We don't want to do any range analysis of such
         --  expressions for two reasons. First, the bounds of a generic type
         --  itself are junk and cannot be used for any kind of analysis.
         --  Second, we may have a case where the range at run time is indeed
         --  known, but we don't want to do compile time analysis in the
         --  template based on that range since in an instance the value may be
         --  static, and able to be elaborated without reference to the bounds
         --  of types involved. As an example, consider:

         --     (F'Pos (F'Last) + 1) > Integer'Last

         --  The expression on the left side of > is Universal_Integer and thus
         --  acquires the type Integer for evaluation at run time, and at run
         --  time it is true that this condition is always False, but within
         --  an instance F may be a type with a static range greater than the
         --  range of Integer, and the expression statically evaluates to True.

         if References_Generic_Formal_Type (L)
              or else
            References_Generic_Formal_Type (R)
         then
            return Unknown;
         end if;

         --  Replace types by base types for the case of values which are not
         --  known to have valid representations. This takes care of properly
         --  dealing with invalid representations.

         if not Assume_Valid then
            if not (Is_Entity_Name (L)
                     and then (Is_Known_Valid (Entity (L))
                                or else Assume_No_Invalid_Values))
            then
               Ltyp := Underlying_Type (Base_Type (Ltyp));
            end if;

            if not (Is_Entity_Name (R)
                     and then (Is_Known_Valid (Entity (R))
                                or else Assume_No_Invalid_Values))
            then
               Rtyp := Underlying_Type (Base_Type (Rtyp));
            end if;
         end if;

         --  First attempt is to decompose the expressions to extract a
         --  constant offset resulting from the use of any of the forms:

         --     expr + literal
         --     expr - literal
         --     typ'Succ (expr)
         --     typ'Pred (expr)

         --  Then we see if the two expressions are the same value, and if so
         --  the result is obtained by comparing the offsets.

         --  Note: the reason we do this test first is that it returns only
         --  decisive results (with diff set), where other tests, like the
         --  range test, may not be as so decisive. Consider for example
         --  J .. J + 1. This code can conclude LT with a difference of 1,
         --  even if the range of J is not known.

         declare
            Lnode : Node_Id;
            Loffs : Uint;
            Rnode : Node_Id;
            Roffs : Uint;

         begin
            Compare_Decompose (L, Lnode, Loffs);
            Compare_Decompose (R, Rnode, Roffs);

            if Is_Same_Value (Lnode, Rnode) then
               if Loffs = Roffs then
                  return EQ;
               end if;

               --  When the offsets are not equal, we can go farther only if
               --  the types are not modular (e.g. X < X + 1 is False if X is
               --  the largest number).

               if not Is_Modular_Integer_Type (Ltyp)
                 and then not Is_Modular_Integer_Type (Rtyp)
               then
                  if Loffs < Roffs then
                     Diff.all := Roffs - Loffs;
                     return LT;
                  else
                     Diff.all := Loffs - Roffs;
                     return GT;
                  end if;
               end if;
            end if;
         end;

         --  Next, try range analysis and see if operand ranges are disjoint

         declare
            LOK, ROK : Boolean;
            LLo, LHi : Uint;
            RLo, RHi : Uint;

            Single : Boolean;
            --  True if each range is a single point

         begin
            Determine_Range (L, LOK, LLo, LHi, Assume_Valid);
            Determine_Range (R, ROK, RLo, RHi, Assume_Valid);

            if LOK and ROK then
               Single := LLo = LHi and then RLo = RHi;

               if LHi < RLo then
                  if Single and Assume_Valid then
                     Diff.all := RLo - LLo;
                  end if;

                  return LT;

               elsif RHi < LLo then
                  if Single and Assume_Valid then
                     Diff.all := LLo - RLo;
                  end if;

                  return GT;

               elsif Single and then LLo = RLo then

                  --  If the range includes a single literal and we can assume
                  --  validity then the result is known even if an operand is
                  --  not static.

                  if Assume_Valid then
                     return EQ;
                  else
                     return Unknown;
                  end if;

               elsif LHi = RLo then
                  return LE;

               elsif RHi = LLo then
                  return GE;

               elsif not Is_Known_Valid_Operand (L)
                 and then not Assume_Valid
               then
                  if Is_Same_Value (L, R) then
                     return EQ;
                  else
                     return Unknown;
                  end if;
               end if;

            --  If the range of either operand cannot be determined, nothing
            --  further can be inferred.

            else
               return Unknown;
            end if;
         end;

         --  Here is where we check for comparisons against maximum bounds of
         --  types, where we know that no value can be outside the bounds of
         --  the subtype. Note that this routine is allowed to assume that all
         --  expressions are within their subtype bounds. Callers wishing to
         --  deal with possibly invalid values must in any case take special
         --  steps (e.g. conversions to larger types) to avoid this kind of
         --  optimization, which is always considered to be valid. We do not
         --  attempt this optimization with generic types, since the type
         --  bounds may not be meaningful in this case.

         --  We are in danger of an infinite recursion here. It does not seem
         --  useful to go more than one level deep, so the parameter Rec is
         --  used to protect ourselves against this infinite recursion.

         if not Rec then

            --  See if we can get a decisive check against one operand and a
            --  bound of the other operand (four possible tests here). Note
            --  that we avoid testing junk bounds of a generic type.

            if not Is_Generic_Type (Rtyp) then
               case Compile_Time_Compare (L, Type_Low_Bound (Rtyp),
                                          Discard'Access,
                                          Assume_Valid, Rec => True)
               is
                  when LT => return LT;
                  when LE => return LE;
                  when EQ => return LE;
                  when others => null;
               end case;

               case Compile_Time_Compare (L, Type_High_Bound (Rtyp),
                                          Discard'Access,
                                          Assume_Valid, Rec => True)
               is
                  when GT => return GT;
                  when GE => return GE;
                  when EQ => return GE;
                  when others => null;
               end case;
            end if;

            if not Is_Generic_Type (Ltyp) then
               case Compile_Time_Compare (Type_Low_Bound (Ltyp), R,
                                          Discard'Access,
                                          Assume_Valid, Rec => True)
               is
                  when GT => return GT;
                  when GE => return GE;
                  when EQ => return GE;
                  when others => null;
               end case;

               case Compile_Time_Compare (Type_High_Bound (Ltyp), R,
                                          Discard'Access,
                                          Assume_Valid, Rec => True)
               is
                  when LT => return LT;
                  when LE => return LE;
                  when EQ => return LE;
                  when others => null;
               end case;
            end if;
         end if;

         --  Next attempt is to see if we have an entity compared with a
         --  compile-time-known value, where there is a current value
         --  conditional for the entity which can tell us the result.

         declare
            Var : Node_Id;
            --  Entity variable (left operand)

            Val : Uint;
            --  Value (right operand)

            Inv : Boolean;
            --  If False, we have reversed the operands

            Op : Node_Kind;
            --  Comparison operator kind from Get_Current_Value_Condition call

            Opn : Node_Id;
            --  Value from Get_Current_Value_Condition call

            Opv : Uint;
            --  Value of Opn

            Result : Compare_Result;
            --  Known result before inversion

         begin
            if Is_Entity_Name (L)
              and then Compile_Time_Known_Value (R)
            then
               Var := L;
               Val := Expr_Value (R);
               Inv := False;

            elsif Is_Entity_Name (R)
              and then Compile_Time_Known_Value (L)
            then
               Var := R;
               Val := Expr_Value (L);
               Inv := True;

               --  That was the last chance at finding a compile time result

            else
               return Unknown;
            end if;

            Get_Current_Value_Condition (Var, Op, Opn);

            --  That was the last chance, so if we got nothing return

            if No (Opn) then
               return Unknown;
            end if;

            Opv := Expr_Value (Opn);

            --  We got a comparison, so we might have something interesting

            --  Convert LE to LT and GE to GT, just so we have fewer cases

            if Op = N_Op_Le then
               Op := N_Op_Lt;
               Opv := Opv + 1;

            elsif Op = N_Op_Ge then
               Op := N_Op_Gt;
               Opv := Opv - 1;
            end if;

            --  Deal with equality case

            if Op = N_Op_Eq then
               if Val = Opv then
                  Result := EQ;
               elsif Opv < Val then
                  Result := LT;
               else
                  Result := GT;
               end if;

            --  Deal with inequality case

            elsif Op = N_Op_Ne then
               if Val = Opv then
                  Result := NE;
               else
                  return Unknown;
               end if;

            --  Deal with greater than case

            elsif Op = N_Op_Gt then
               if Opv >= Val then
                  Result := GT;
               elsif Opv = Val - 1 then
                  Result := GE;
               else
                  return Unknown;
               end if;

            --  Deal with less than case

            else pragma Assert (Op = N_Op_Lt);
               if Opv <= Val then
                  Result := LT;
               elsif Opv = Val + 1 then
                  Result := LE;
               else
                  return Unknown;
               end if;
            end if;

            --  Deal with inverting result

            if Inv then
               case Result is
                  when GT     => return LT;
                  when GE     => return LE;
                  when LT     => return GT;
                  when LE     => return GE;
                  when others => return Result;
               end case;
            end if;

            return Result;
         end;
      end if;
   end Compile_Time_Compare;

   -------------------------------
   -- Compile_Time_Known_Bounds --
   -------------------------------

   function Compile_Time_Known_Bounds (T : Entity_Id) return Boolean is
      Indx : Node_Id;
      Typ  : Entity_Id;

   begin
      if T = Any_Composite or else not Is_Array_Type (T) then
         return False;
      end if;

      Indx := First_Index (T);
      while Present (Indx) loop
         Typ := Underlying_Type (Etype (Indx));

         --  Never look at junk bounds of a generic type

         if Is_Generic_Type (Typ) then
            return False;
         end if;

         --  Otherwise check bounds for compile-time-known

         if not Compile_Time_Known_Value (Type_Low_Bound (Typ)) then
            return False;
         elsif not Compile_Time_Known_Value (Type_High_Bound (Typ)) then
            return False;
         else
            Next_Index (Indx);
         end if;
      end loop;

      return True;
   end Compile_Time_Known_Bounds;

   ------------------------------
   -- Compile_Time_Known_Value --
   ------------------------------

   function Compile_Time_Known_Value (Op : Node_Id) return Boolean is
      K      : constant Node_Kind := Nkind (Op);
      CV_Ent : CV_Entry renames CV_Cache (Nat (Op) mod CV_Cache_Size);

   begin
      --  Never known at compile time if bad type or raises Constraint_Error
      --  or empty (which can occur as a result of a previous error or in the
      --  case of e.g. an imported constant).

      if No (Op) then
         return False;

      elsif Op = Error
        or else Nkind (Op) not in N_Has_Etype
        or else Etype (Op) = Any_Type
        or else Raises_Constraint_Error (Op)
      then
         return False;
      end if;

      --  If we have an entity name, then see if it is the name of a constant
      --  and if so, test the corresponding constant value, or the name of an
      --  enumeration literal, which is always a constant.

      if Present (Etype (Op)) and then Is_Entity_Name (Op) then
         declare
            Ent : constant Entity_Id := Entity (Op);
            Val : Node_Id;

         begin
            --  Never known at compile time if it is a packed array value. We
            --  might want to try to evaluate these at compile time one day,
            --  but we do not make that attempt now.

            if Is_Packed_Array_Impl_Type (Etype (Op)) then
               return False;

            elsif Ekind (Ent) = E_Enumeration_Literal then
               return True;

            elsif Ekind (Ent) = E_Constant then
               Val := Constant_Value (Ent);

               if Present (Val) then

                  --  Guard against an illegal deferred constant whose full
                  --  view is initialized with a reference to itself. Treat
                  --  this case as a value not known at compile time.

                  if Is_Entity_Name (Val) and then Entity (Val) = Ent then
                     return False;
                  else
                     return Compile_Time_Known_Value (Val);
                  end if;

               --  Otherwise, the constant does not have a compile-time-known
               --  value.

               else
                  return False;
               end if;
            end if;
         end;

      --  We have a value, see if it is compile-time-known

      else
         --  Integer literals are worth storing in the cache

         if K = N_Integer_Literal then
            CV_Ent.N := Op;
            CV_Ent.V := Intval (Op);
            return True;

         --  Other literals and NULL are known at compile time

         elsif K in
           N_Character_Literal | N_Real_Literal | N_String_Literal | N_Null
         then
            return True;

         --  Evaluate static discriminants, to eliminate dead paths and
         --  redundant discriminant checks.

         elsif Is_Static_Discriminant_Component (Op) then
            return True;
         end if;
      end if;

      --  If we fall through, not known at compile time

      return False;

   --  If we get an exception while trying to do this test, then some error
   --  has occurred, and we simply say that the value is not known after all

   exception
      when others =>
         --  With debug flag K we will get an exception unless an error has
         --  already occurred (useful for debugging).

         if Debug_Flag_K then
            Check_Error_Detected;
         end if;

         return False;
   end Compile_Time_Known_Value;

   ---------------------------------------
   -- CRT_Safe_Compile_Time_Known_Value --
   ---------------------------------------

   function CRT_Safe_Compile_Time_Known_Value (Op : Node_Id) return Boolean is
   begin
      if (Configurable_Run_Time_Mode or No_Run_Time_Mode)
        and then not Is_OK_Static_Expression (Op)
      then
         return False;
      else
         return Compile_Time_Known_Value (Op);
      end if;
   end CRT_Safe_Compile_Time_Known_Value;

   -----------------
   -- Eval_Actual --
   -----------------

   --  This is only called for actuals of functions that are not predefined
   --  operators (which have already been rewritten as operators at this
   --  stage), so the call can never be folded, and all that needs doing for
   --  the actual is to do the check for a non-static context.

   procedure Eval_Actual (N : Node_Id) is
   begin
      Check_Non_Static_Context (N);
   end Eval_Actual;

   --------------------
   -- Eval_Allocator --
   --------------------

   --  Allocators are never static, so all we have to do is to do the
   --  check for a non-static context if an expression is present.

   procedure Eval_Allocator (N : Node_Id) is
      Expr : constant Node_Id := Expression (N);
   begin
      if Nkind (Expr) = N_Qualified_Expression then
         Check_Non_Static_Context (Expression (Expr));
      end if;
   end Eval_Allocator;

   ------------------------
   -- Eval_Arithmetic_Op --
   ------------------------

   --  Arithmetic operations are static functions, so the result is static
   --  if both operands are static (RM 4.9(7), 4.9(20)).

   procedure Eval_Arithmetic_Op (N : Node_Id) is
      Left  : constant Node_Id   := Left_Opnd (N);
      Right : constant Node_Id   := Right_Opnd (N);
      Ltype : constant Entity_Id := Etype (Left);
      Rtype : constant Entity_Id := Etype (Right);
      Otype : Entity_Id          := Empty;
      Stat  : Boolean;
      Fold  : Boolean;

   begin
      --  If not foldable we are done

      Test_Expression_Is_Foldable (N, Left, Right, Stat, Fold);

      if not Fold then
         return;
      end if;

      --  Otherwise attempt to fold

      if Is_Universal_Numeric_Type (Etype (Left))
           and then
         Is_Universal_Numeric_Type (Etype (Right))
      then
         Otype := Find_Universal_Operator_Type (N);
      end if;

      --  Fold for cases where both operands are of integer type

      if Is_Integer_Type (Ltype) and then Is_Integer_Type (Rtype) then
         declare
            Left_Int  : constant Uint := Expr_Value (Left);
            Right_Int : constant Uint := Expr_Value (Right);
            Result    : Uint;

         begin
            case Nkind (N) is
               when N_Op_Add =>
                  Result := Left_Int + Right_Int;

               when N_Op_Subtract =>
                  Result := Left_Int - Right_Int;

               when N_Op_Multiply =>
                  if OK_Bits
                       (N, UI_From_Int
                             (Num_Bits (Left_Int) + Num_Bits (Right_Int)))
                  then
                     Result := Left_Int * Right_Int;
                  else
                     Result := Left_Int;
                  end if;

               when N_Op_Divide =>

                  --  The exception Constraint_Error is raised by integer
                  --  division, rem and mod if the right operand is zero.

                  if Right_Int = 0 then

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

                     Apply_Compile_Time_Constraint_Error
                       (N, "division by zero", CE_Divide_By_Zero,
                        Loc  => Sloc (Right),
                        Warn => not Stat or SPARK_Mode = On);
                     return;

                  --  Otherwise we can do the division

                  else
                     Result := Left_Int / Right_Int;
                  end if;

               when N_Op_Mod =>

                  --  The exception Constraint_Error is raised by integer
                  --  division, rem and mod if the right operand is zero.

                  if Right_Int = 0 then

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

                     Apply_Compile_Time_Constraint_Error
                       (N, "mod with zero divisor", CE_Divide_By_Zero,
                        Loc  => Sloc (Right),
                        Warn => not Stat or SPARK_Mode = On);
                     return;

                  else
                     Result := Left_Int mod Right_Int;
                  end if;

               when N_Op_Rem =>

                  --  The exception Constraint_Error is raised by integer
                  --  division, rem and mod if the right operand is zero.

                  if Right_Int = 0 then

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

                     Apply_Compile_Time_Constraint_Error
                       (N, "rem with zero divisor", CE_Divide_By_Zero,
                        Loc  => Sloc (Right),
                        Warn => not Stat or SPARK_Mode = On);
                     return;

                  else
                     Result := Left_Int rem Right_Int;
                  end if;

               when others =>
                  raise Program_Error;
            end case;

            --  Adjust the result by the modulus if the type is a modular type

            if Is_Modular_Integer_Type (Ltype) then
               Result := Result mod Modulus (Ltype);
            end if;

            Check_Non_Static_Context_For_Overflow (N, Stat, Result);

            --  If we get here we can fold the result

            Fold_Uint (N, Result, Stat);
         end;

      --  Cases where at least one operand is a real. We handle the cases of
      --  both reals, or mixed/real integer cases (the latter happen only for
      --  divide and multiply, and the result is always real).

      elsif Is_Real_Type (Ltype) or else Is_Real_Type (Rtype) then
         declare
            Left_Real  : Ureal;
            Right_Real : Ureal;
            Result     : Ureal;

         begin
            if Is_Real_Type (Ltype) then
               Left_Real := Expr_Value_R (Left);
            else
               Left_Real := UR_From_Uint (Expr_Value (Left));
            end if;

            if Is_Real_Type (Rtype) then
               Right_Real := Expr_Value_R (Right);
            else
               Right_Real := UR_From_Uint (Expr_Value (Right));
            end if;

            if Nkind (N) = N_Op_Add then
               Result := Left_Real + Right_Real;

            elsif Nkind (N) = N_Op_Subtract then
               Result := Left_Real - Right_Real;

            elsif Nkind (N) = N_Op_Multiply then
               Result := Left_Real * Right_Real;

            else pragma Assert (Nkind (N) = N_Op_Divide);
               if UR_Is_Zero (Right_Real) then
                  Apply_Compile_Time_Constraint_Error
                    (N, "division by zero", CE_Divide_By_Zero,
                     Loc => Sloc (Right));
                  return;
               end if;

               Result := Left_Real / Right_Real;
            end if;

            Fold_Ureal (N, Result, Stat);
         end;
      end if;

      --  If the operator was resolved to a specific type, make sure that type
      --  is frozen even if the expression is folded into a literal (which has
      --  a universal type).

      if Present (Otype) then
         Freeze_Before (N, Otype);
      end if;
   end Eval_Arithmetic_Op;

   ----------------------------
   -- Eval_Character_Literal --
   ----------------------------

   --  Nothing to be done

   procedure Eval_Character_Literal (N : Node_Id) is
      pragma Warnings (Off, N);
   begin
      null;
   end Eval_Character_Literal;

   ---------------
   -- Eval_Call --
   ---------------

   --  Static function calls are either calls to predefined operators
   --  with static arguments, or calls to functions that rename a literal.
   --  Only the latter case is handled here, predefined operators are
   --  constant-folded elsewhere.

   --  If the function is itself inherited the literal of the parent type must
   --  be explicitly converted to the return type of the function.

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

   begin
      if Nkind (N) = N_Function_Call
        and then No (Parameter_Associations (N))
        and then Is_Entity_Name (Name (N))
        and then Present (Alias (Entity (Name (N))))
        and then Is_Enumeration_Type (Base_Type (Typ))
      then
         Lit := Ultimate_Alias (Entity (Name (N)));

         if Ekind (Lit) = E_Enumeration_Literal then
            if Base_Type (Etype (Lit)) /= Base_Type (Typ) then
               Rewrite
                 (N, Convert_To (Typ, New_Occurrence_Of (Lit, Loc)));
            else
               Rewrite (N, New_Occurrence_Of (Lit, Loc));
            end if;

            Resolve (N, Typ);
         end if;

      elsif Nkind (N) = N_Function_Call
        and then Is_Entity_Name (Name (N))
        and then Is_Intrinsic_Subprogram (Entity (Name (N)))
      then
         Eval_Intrinsic_Call (N, Entity (Name (N)));

      --  Ada 2022 (AI12-0075): If checking for potentially static expressions
      --  is enabled and we have a call to a static function, substitute a
      --  static value for the call, to allow folding the expression. This
      --  supports checking the requirement of RM 6.8(5.3/5) in
      --  Analyze_Expression_Function.

      elsif Checking_Potentially_Static_Expression
        and then Is_Static_Function_Call (N)
      then
         Fold_Dummy (N, Typ);
      end if;
   end Eval_Call;

   --------------------------
   -- Eval_Case_Expression --
   --------------------------

   --  A conditional expression is static if all its conditions and dependent
   --  expressions are static. Note that we do not care if the dependent
   --  expressions raise CE, except for the one that will be selected.

   procedure Eval_Case_Expression (N : Node_Id) is
      Alt    : Node_Id;
      Choice : Node_Id;

   begin
      Set_Is_Static_Expression (N, False);

      if Error_Posted (Expression (N))
        or else not Is_Static_Expression (Expression (N))
      then
         Check_Non_Static_Context (Expression (N));
         return;
      end if;

      --  First loop, make sure all the alternatives are static expressions
      --  none of which raise Constraint_Error. We make the Constraint_Error
      --  check because part of the legality condition for a correct static
      --  case expression is that the cases are covered, like any other case
      --  expression. And we can't do that if any of the conditions raise an
      --  exception, so we don't even try to evaluate if that is the case.

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

         --  The expression must be static, but we don't care at this stage
         --  if it raises Constraint_Error (the alternative might not match,
         --  in which case the expression is statically unevaluated anyway).

         if not Is_Static_Expression (Expression (Alt)) then
            Check_Non_Static_Context (Expression (Alt));
            return;
         end if;

         --  The choices of a case always have to be static, and cannot raise
         --  an exception. If this condition is not met, then the expression
         --  is plain illegal, so just abandon evaluation attempts. No need
         --  to check non-static context when we have something illegal anyway.

         if not Is_OK_Static_Choice_List (Discrete_Choices (Alt)) then
            return;
         end if;

         Next (Alt);
      end loop;

      --  OK, if the above loop gets through it means that all choices are OK
      --  static (don't raise exceptions), so the whole case is static, and we
      --  can find the matching alternative.

      Set_Is_Static_Expression (N);

      --  Now to deal with propagating a possible Constraint_Error

      --  If the selecting expression raises CE, propagate and we are done

      if Raises_Constraint_Error (Expression (N)) then
         Set_Raises_Constraint_Error (N);

      --  Otherwise we need to check the alternatives to find the matching
      --  one. CE's in other than the matching one are not relevant. But we
      --  do need to check the matching one. Unlike the first loop, we do not
      --  have to go all the way through, when we find the matching one, quit.

      else
         Alt := First (Alternatives (N));
         Search : loop

            --  We must find a match among the alternatives. If not, this must
            --  be due to other errors, so just ignore, leaving as non-static.

            if No (Alt) then
               Set_Is_Static_Expression (N, False);
               return;
            end if;

            --  Otherwise loop through choices of this alternative

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

               --  If we find a matching choice, then the Expression of this
               --  alternative replaces N (Raises_Constraint_Error flag is
               --  included, so we don't have to special case that).

               if Choice_Matches (Expression (N), Choice) = Match then
                  Rewrite (N, Relocate_Node (Expression (Alt)));
                  return;
               end if;

               Next (Choice);
            end loop;

            Next (Alt);
         end loop Search;
      end if;
   end Eval_Case_Expression;

   ------------------------
   -- Eval_Concatenation --
   ------------------------

   --  Concatenation is a static function, so the result is static if both
   --  operands are static (RM 4.9(7), 4.9(21)).

   procedure Eval_Concatenation (N : Node_Id) is
      Left  : constant Node_Id   := Left_Opnd (N);
      Right : constant Node_Id   := Right_Opnd (N);
      C_Typ : constant Entity_Id := Root_Type (Component_Type (Etype (N)));
      Stat  : Boolean;
      Fold  : Boolean;

   begin
      --  Concatenation is never static in Ada 83, so if Ada 83 check operand
      --  non-static context.

      if Ada_Version = Ada_83
        and then Comes_From_Source (N)
      then
         Check_Non_Static_Context (Left);
         Check_Non_Static_Context (Right);
         return;
      end if;

      --  If not foldable we are done. In principle concatenation that yields
      --  any string type is static (i.e. an array type of character types).
      --  However, character types can include enumeration literals, and
      --  concatenation in that case cannot be described by a literal, so we
      --  only consider the operation static if the result is an array of
      --  (a descendant of) a predefined character type.

      Test_Expression_Is_Foldable (N, Left, Right, Stat, Fold);

      if not (Is_Standard_Character_Type (C_Typ) and then Fold) then
         Set_Is_Static_Expression (N, False);
         return;
      end if;

      --  Compile time string concatenation

      --  ??? Note that operands that are aggregates can be marked as static,
      --  so we should attempt at a later stage to fold concatenations with
      --  such aggregates.

      declare
         Left_Str   : constant Node_Id := Get_String_Val (Left);
         Left_Len   : Nat;
         Right_Str  : constant Node_Id := Get_String_Val (Right);
         Folded_Val : String_Id        := No_String;

      begin
         --  Establish new string literal, and store left operand. We make
         --  sure to use the special Start_String that takes an operand if
         --  the left operand is a string literal. Since this is optimized
         --  in the case where that is the most recently created string
         --  literal, we ensure efficient time/space behavior for the
         --  case of a concatenation of a series of string literals.

         if Nkind (Left_Str) = N_String_Literal then
            Left_Len := String_Length (Strval (Left_Str));

            --  If the left operand is the empty string, and the right operand
            --  is a string literal (the case of "" & "..."), the result is the
            --  value of the right operand. This optimization is important when
            --  Is_Folded_In_Parser, to avoid copying an enormous right
            --  operand.

            if Left_Len = 0 and then Nkind (Right_Str) = N_String_Literal then
               Folded_Val := Strval (Right_Str);
            else
               Start_String (Strval (Left_Str));
            end if;

         else
            Start_String;
            Store_String_Char (UI_To_CC (Char_Literal_Value (Left_Str)));
            Left_Len := 1;
         end if;

         --  Now append the characters of the right operand, unless we
         --  optimized the "" & "..." case above.

         if Nkind (Right_Str) = N_String_Literal then
            if Left_Len /= 0 then
               Store_String_Chars (Strval (Right_Str));
               Folded_Val := End_String;
            end if;
         else
            Store_String_Char (UI_To_CC (Char_Literal_Value (Right_Str)));
            Folded_Val := End_String;
         end if;

         Set_Is_Static_Expression (N, Stat);

         --  If left operand is the empty string, the result is the
         --  right operand, including its bounds if anomalous.

         if Left_Len = 0
           and then Is_Array_Type (Etype (Right))
           and then Etype (Right) /= Any_String
         then
            Set_Etype (N, Etype (Right));
         end if;

         Fold_Str (N, Folded_Val, Static => Stat);
      end;
   end Eval_Concatenation;

   ----------------------
   -- Eval_Entity_Name --
   ----------------------

   --  This procedure is used for identifiers and expanded names other than
   --  named numbers (see Eval_Named_Integer, Eval_Named_Real. These are
   --  static if they denote a static constant (RM 4.9(6)) or if the name
   --  denotes an enumeration literal (RM 4.9(22)).

   procedure Eval_Entity_Name (N : Node_Id) is
      Def_Id : constant Entity_Id := Entity (N);
      Val    : Node_Id;

   begin
      --  Enumeration literals are always considered to be constants
      --  and cannot raise Constraint_Error (RM 4.9(22)).

      if Ekind (Def_Id) = E_Enumeration_Literal then
         Set_Is_Static_Expression (N);
         return;

      --  A name is static if it denotes a static constant (RM 4.9(5)), and
      --  we also copy Raise_Constraint_Error. Notice that even if non-static,
      --  it does not violate 10.2.1(8) here, since this is not a variable.

      elsif Ekind (Def_Id) = E_Constant then

         --  Deferred constants must always be treated as nonstatic outside the
         --  scope of their full view.

         if Present (Full_View (Def_Id))
           and then not In_Open_Scopes (Scope (Def_Id))
         then
            Val := Empty;
         else
            Val := Constant_Value (Def_Id);
         end if;

         if Present (Val) then
            Set_Is_Static_Expression
              (N, Is_Static_Expression (Val)
                    and then Is_Static_Subtype (Etype (Def_Id)));
            Set_Raises_Constraint_Error (N, Raises_Constraint_Error (Val));

            if not Is_Static_Expression (N)
              and then not Is_Generic_Type (Etype (N))
            then
               Validate_Static_Object_Name (N);
            end if;

            --  Mark constant condition in SCOs

            if Generate_SCO
              and then Comes_From_Source (N)
              and then Is_Boolean_Type (Etype (Def_Id))
              and then Compile_Time_Known_Value (N)
            then
               Set_SCO_Condition (N, Expr_Value_E (N) = Standard_True);
            end if;

            return;
         end if;

      --  Ada 2022 (AI12-0075): If checking for potentially static expressions
      --  is enabled and we have a reference to a formal parameter of mode in,
      --  substitute a static value for the reference, to allow folding the
      --  expression. This supports checking the requirement of RM 6.8(5.3/5)
      --  in Analyze_Expression_Function.

      elsif Ekind (Def_Id) = E_In_Parameter
        and then Checking_Potentially_Static_Expression
        and then Is_Static_Function (Scope (Def_Id))
      then
         Fold_Dummy (N, Etype (Def_Id));
      end if;

      --  Fall through if the name is not static

      Validate_Static_Object_Name (N);
   end Eval_Entity_Name;

   ------------------------
   -- Eval_If_Expression --
   ------------------------

   --  We can fold to a static expression if the condition and both dependent
   --  expressions are static. Otherwise, the only required processing is to do
   --  the check for non-static context for the then and else expressions.

   procedure Eval_If_Expression (N : Node_Id) is
      Condition  : constant Node_Id := First (Expressions (N));
      Then_Expr  : constant Node_Id := Next (Condition);
      Else_Expr  : constant Node_Id := Next (Then_Expr);
      Result     : Node_Id;
      Non_Result : Node_Id;

      Rstat : constant Boolean :=
                Is_Static_Expression (Condition)
                  and then
                Is_Static_Expression (Then_Expr)
                  and then
                Is_Static_Expression (Else_Expr);
      --  True if result is static

   begin
      --  If result not static, nothing to do, otherwise set static result

      if not Rstat then
         return;
      else
         Set_Is_Static_Expression (N);
      end if;

      --  If any operand is Any_Type, just propagate to result and do not try
      --  to fold, this prevents cascaded errors.

      if Etype (Condition) = Any_Type or else
         Etype (Then_Expr) = Any_Type or else
         Etype (Else_Expr) = Any_Type
      then
         Set_Etype (N, Any_Type);
         Set_Is_Static_Expression (N, False);
         return;
      end if;

      --  If condition raises Constraint_Error then we have already signaled
      --  an error, and we just propagate to the result and do not fold.

      if Raises_Constraint_Error (Condition) then
         Set_Raises_Constraint_Error (N);
         return;
      end if;

      --  Static case where we can fold. Note that we don't try to fold cases
      --  where the condition is known at compile time, but the result is
      --  non-static. This avoids possible cases of infinite recursion where
      --  the expander puts in a redundant test and we remove it. Instead we
      --  deal with these cases in the expander.

      --  Select result operand

      if Is_True (Expr_Value (Condition)) then
         Result     := Then_Expr;
         Non_Result := Else_Expr;
      else
         Result     := Else_Expr;
         Non_Result := Then_Expr;
      end if;

      --  Note that it does not matter if the non-result operand raises a
      --  Constraint_Error, but if the result raises Constraint_Error then we
      --  replace the node with a raise Constraint_Error. This will properly
      --  propagate Raises_Constraint_Error since this flag is set in Result.

      if Raises_Constraint_Error (Result) then
         Rewrite_In_Raise_CE (N, Result);
         Check_Non_Static_Context (Non_Result);

      --  Otherwise the result operand replaces the original node

      else
         Rewrite (N, Relocate_Node (Result));
         Set_Is_Static_Expression (N);
      end if;
   end Eval_If_Expression;

   ----------------------------
   -- Eval_Indexed_Component --
   ----------------------------

   --  Indexed components are never static, so we need to perform the check
   --  for non-static context on the index values. Then, we check if the
   --  value can be obtained at compile time, even though it is non-static.

   procedure Eval_Indexed_Component (N : Node_Id) is
      Expr : Node_Id;

   begin
      --  Check for non-static context on index values

      Expr := First (Expressions (N));
      while Present (Expr) loop
         Check_Non_Static_Context (Expr);
         Next (Expr);
      end loop;

      --  If the indexed component appears in an object renaming declaration
      --  then we do not want to try to evaluate it, since in this case we
      --  need the identity of the array element.

      if Nkind (Parent (N)) = N_Object_Renaming_Declaration then
         return;

      --  Similarly if the indexed component appears as the prefix of an
      --  attribute we don't want to evaluate it, because at least for
      --  some cases of attributes we need the identify (e.g. Access, Size).

      elsif Nkind (Parent (N)) = N_Attribute_Reference then
         return;
      end if;

      --  Note: there are other cases, such as the left side of an assignment,
      --  or an OUT parameter for a call, where the replacement results in the
      --  illegal use of a constant, But these cases are illegal in the first
      --  place, so the replacement, though silly, is harmless.

      --  Now see if this is a constant array reference

      if List_Length (Expressions (N)) = 1
        and then Is_Entity_Name (Prefix (N))
        and then Ekind (Entity (Prefix (N))) = E_Constant
        and then Present (Constant_Value (Entity (Prefix (N))))
      then
         declare
            Loc : constant Source_Ptr := Sloc (N);
            Arr : constant Node_Id    := Constant_Value (Entity (Prefix (N)));
            Sub : constant Node_Id    := First (Expressions (N));

            Atyp : Entity_Id;
            --  Type of array

            Lin : Nat;
            --  Linear one's origin subscript value for array reference

            Lbd : Node_Id;
            --  Lower bound of the first array index

            Elm : Node_Id;
            --  Value from constant array

         begin
            Atyp := Etype (Arr);

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

            --  If we have an array type (we should have but perhaps there are
            --  error cases where this is not the case), then see if we can do
            --  a constant evaluation of the array reference.

            if Is_Array_Type (Atyp) and then Atyp /= Any_Composite then
               if Ekind (Atyp) = E_String_Literal_Subtype then
                  Lbd := String_Literal_Low_Bound (Atyp);
               else
                  Lbd := Type_Low_Bound (Etype (First_Index (Atyp)));
               end if;

               if Compile_Time_Known_Value (Sub)
                 and then Nkind (Arr) = N_Aggregate
                 and then Compile_Time_Known_Value (Lbd)
                 and then Is_Discrete_Type (Component_Type (Atyp))
               then
                  Lin := UI_To_Int (Expr_Value (Sub) - Expr_Value (Lbd)) + 1;

                  if List_Length (Expressions (Arr)) >= Lin then
                     Elm := Pick (Expressions (Arr), Lin);

                     --  If the resulting expression is compile-time-known,
                     --  then we can rewrite the indexed component with this
                     --  value, being sure to mark the result as non-static.
                     --  We also reset the Sloc, in case this generates an
                     --  error later on (e.g. 136'Access).

                     if Compile_Time_Known_Value (Elm) then
                        Rewrite (N, Duplicate_Subexpr_No_Checks (Elm));
                        Set_Is_Static_Expression (N, False);
                        Set_Sloc (N, Loc);
                     end if;
                  end if;

               --  We can also constant-fold if the prefix is a string literal.
               --  This will be useful in an instantiation or an inlining.

               elsif Compile_Time_Known_Value (Sub)
                 and then Nkind (Arr) = N_String_Literal
                 and then Compile_Time_Known_Value (Lbd)
                 and then Expr_Value (Lbd) = 1
                 and then Expr_Value (Sub) <=
                   String_Literal_Length (Etype (Arr))
               then
                  declare
                     C : constant Char_Code :=
                           Get_String_Char (Strval (Arr),
                             UI_To_Int (Expr_Value (Sub)));
                  begin
                     Set_Character_Literal_Name (C);

                     Elm :=
                       Make_Character_Literal (Loc,
                         Chars              => Name_Find,
                         Char_Literal_Value => UI_From_CC (C));
                     Set_Etype (Elm, Component_Type (Atyp));
                     Rewrite (N, Duplicate_Subexpr_No_Checks (Elm));
                     Set_Is_Static_Expression (N, False);
                  end;
               end if;
            end if;
         end;
      end if;
   end Eval_Indexed_Component;

   --------------------------
   -- Eval_Integer_Literal --
   --------------------------

   --  Numeric literals are static (RM 4.9(1)), and have already been marked
   --  as static by the analyzer. The reason we did it that early is to allow
   --  the possibility of turning off the Is_Static_Expression flag after
   --  analysis, but before resolution, when integer literals are generated in
   --  the expander that do not correspond to static expressions.

   procedure Eval_Integer_Literal (N : Node_Id) is
      function In_Any_Integer_Context (K : Node_Kind) return Boolean;
      --  If the literal is resolved with a specific type in a context where
      --  the expected type is Any_Integer, there are no range checks on the
      --  literal. By the time the literal is evaluated, it carries the type
      --  imposed by the enclosing expression, and we must recover the context
      --  to determine that Any_Integer is meant.

      ----------------------------
      -- In_Any_Integer_Context --
      ----------------------------

      function In_Any_Integer_Context (K : Node_Kind) return Boolean is
      begin
         --  Any_Integer also appears in digits specifications for real types,
         --  but those have bounds smaller that those of any integer base type,
         --  so we can safely ignore these cases.

         return K in N_Attribute_Definition_Clause
                   | N_Modular_Type_Definition
                   | N_Number_Declaration
                   | N_Signed_Integer_Type_Definition;
      end In_Any_Integer_Context;

      --  Local variables

      PK  : constant Node_Kind := Nkind (Parent (N));
      Typ : constant Entity_Id := Etype (N);

   --  Start of processing for Eval_Integer_Literal

   begin
      --  If the literal appears in a non-expression context, then it is
      --  certainly appearing in a non-static context, so check it. This is
      --  actually a redundant check, since Check_Non_Static_Context would
      --  check it, but it seems worthwhile to optimize out the call.

      --  Additionally, when the literal appears within an if or case
      --  expression it must be checked as well. However, due to the literal
      --  appearing within a conditional statement, expansion greatly changes
      --  the nature of its context and performing some of the checks within
      --  Check_Non_Static_Context on an expanded literal may lead to spurious
      --  and misleading warnings.

      if (PK not in N_Case_Expression_Alternative | N_Subexpr
           or else (PK in N_Case_Expression_Alternative | N_If_Expression
                     and then
                    Comes_From_Source (N)))
        and then not In_Any_Integer_Context (PK)
      then
         Check_Non_Static_Context (N);
      end if;

      --  Modular integer literals must be in their base range

      if Is_Modular_Integer_Type (Typ)
        and then Is_Out_Of_Range (N, Base_Type (Typ), Assume_Valid => True)
      then
         Out_Of_Range (N);
      end if;
   end Eval_Integer_Literal;

   -------------------------
   -- Eval_Intrinsic_Call --
   -------------------------

   procedure Eval_Intrinsic_Call (N : Node_Id; E : Entity_Id) is

      procedure Eval_Shift (N : Node_Id; E : Entity_Id; Op : Node_Kind);
      --  Evaluate an intrinsic shift call N on the given subprogram E.
      --  Op is the kind for the shift node.

      ----------------
      -- Eval_Shift --
      ----------------

      procedure Eval_Shift (N : Node_Id; E : Entity_Id; Op : Node_Kind) is
         Left   : constant Node_Id := First_Actual (N);
         Right  : constant Node_Id := Next_Actual (Left);
         Static : constant Boolean := Is_Static_Function (E);

      begin
         if Static then
            if Checking_Potentially_Static_Expression then
               Fold_Dummy (N, Etype (N));
               return;
            end if;
         end if;

         Fold_Shift
           (N, Left, Right, Op, Static => Static, Check_Elab => not Static);
      end Eval_Shift;

      Nam : Name_Id;

   begin
      --  Nothing to do if the intrinsic is handled by the back end.

      if Present (Interface_Name (E)) then
         return;
      end if;

      --  Intrinsic calls as part of a static function is a (core)
      --  language extension.

      if Checking_Potentially_Static_Expression
        and then not Core_Extensions_Allowed
      then
         return;
      end if;

      --  If we have a renaming, expand the call to the original operation,
      --  which must itself be intrinsic, since renaming requires matching
      --  conventions and this has already been checked.

      if Present (Alias (E)) then
         Eval_Intrinsic_Call (N, Alias (E));
         return;
      end if;

      --  If the intrinsic subprogram is generic, gets its original name

      if Present (Parent (E))
        and then Present (Generic_Parent (Parent (E)))
      then
         Nam := Chars (Generic_Parent (Parent (E)));
      else
         Nam := Chars (E);
      end if;

      case Nam is
         when Name_Shift_Left  =>
            Eval_Shift (N, E, N_Op_Shift_Left);
         when Name_Shift_Right =>
            Eval_Shift (N, E, N_Op_Shift_Right);
         when Name_Shift_Right_Arithmetic =>
            Eval_Shift (N, E, N_Op_Shift_Right_Arithmetic);
         when others           =>
            null;
      end case;
   end Eval_Intrinsic_Call;

   ---------------------
   -- Eval_Logical_Op --
   ---------------------

   --  Logical operations are static functions, so the result is potentially
   --  static if both operands are potentially static (RM 4.9(7), 4.9(20)).

   procedure Eval_Logical_Op (N : Node_Id) is
      Left      : constant Node_Id := Left_Opnd (N);
      Right     : constant Node_Id := Right_Opnd (N);
      Left_Int  : Uint := No_Uint;
      Right_Int : Uint := No_Uint;
      Stat      : Boolean;
      Fold      : Boolean;

   begin
      --  If not foldable we are done

      Test_Expression_Is_Foldable (N, Left, Right, Stat, Fold);

      if not Fold then
         return;
      end if;

      --  Compile time evaluation of logical operation

      if Is_Modular_Integer_Type (Etype (N)) then
         Left_Int  := Expr_Value (Left);
         Right_Int := Expr_Value (Right);

         declare
            Left_Bits  : Bits (0 .. UI_To_Int (Esize (Etype (N))) - 1);
            Right_Bits : Bits (0 .. UI_To_Int (Esize (Etype (N))) - 1);

         begin
            To_Bits (Left_Int, Left_Bits);
            To_Bits (Right_Int, Right_Bits);

            --  Note: should really be able to use array ops instead of
            --  these loops, but they break the build with a cryptic error
            --  during the bind of gnat1 likely due to a wrong computation
            --  of a date or checksum.

            if Nkind (N) = N_Op_And then
               for J in Left_Bits'Range loop
                  Left_Bits (J) := Left_Bits (J) and Right_Bits (J);
               end loop;

            elsif Nkind (N) = N_Op_Or then
               for J in Left_Bits'Range loop
                  Left_Bits (J) := Left_Bits (J) or Right_Bits (J);
               end loop;

            else
               pragma Assert (Nkind (N) = N_Op_Xor);

               for J in Left_Bits'Range loop
                  Left_Bits (J) := Left_Bits (J) xor Right_Bits (J);
               end loop;
            end if;

            Fold_Uint (N, From_Bits (Left_Bits, Etype (N)), Stat);
         end;

      else
         pragma Assert (Is_Boolean_Type (Etype (N)));

         if Compile_Time_Known_Value (Left)
           and then Compile_Time_Known_Value (Right)
         then
            Right_Int := Expr_Value (Right);
            Left_Int  := Expr_Value (Left);
         end if;

         if Nkind (N) = N_Op_And then

            --  If Left or Right are not compile time known values it means
            --  that the result is always False as per
            --  Test_Expression_Is_Foldable.
            --  Note that in this case, both Right_Int and Left_Int are set
            --  to No_Uint, so need to test for both.

            if No (Right_Int) then
               Fold_Uint (N, Uint_0, Stat);
            else
               Fold_Uint (N,
                 Test (Is_True (Left_Int) and then Is_True (Right_Int)), Stat);
            end if;
         elsif Nkind (N) = N_Op_Or then

            --  If Left or Right are not compile time known values it means
            --  that the result is always True. as per
            --  Test_Expression_Is_Foldable.
            --  Note that in this case, both Right_Int and Left_Int are set
            --  to No_Uint, so need to test for both.

            if No (Right_Int) then
               Fold_Uint (N, Uint_1, Stat);
            else
               Fold_Uint (N,
                 Test (Is_True (Left_Int) or else Is_True (Right_Int)), Stat);
            end if;
         else
            pragma Assert (Nkind (N) = N_Op_Xor);
            Fold_Uint (N,
              Test (Is_True (Left_Int) xor Is_True (Right_Int)), Stat);
         end if;
      end if;
   end Eval_Logical_Op;

   ------------------------
   -- Eval_Membership_Op --
   ------------------------

   --  A membership test is potentially static if the expression is static, and
   --  the range is a potentially static range, or is a subtype mark denoting a
   --  static subtype (RM 4.9(12)).

   procedure Eval_Membership_Op (N : Node_Id) is
      Alts   : constant List_Id := Alternatives (N);
      Choice : constant Node_Id := Right_Opnd (N);
      Expr   : constant Node_Id := Left_Opnd (N);
      Result : Match_Result;

   begin
      --  Ignore if error in either operand, except to make sure that Any_Type
      --  is properly propagated to avoid junk cascaded errors.

      if Etype (Expr) = Any_Type
        or else (Present (Choice) and then Etype (Choice) = Any_Type)
      then
         Set_Etype (N, Any_Type);
         return;
      end if;

      --  If left operand non-static, then nothing to do

      if not Is_Static_Expression (Expr) then
         return;
      end if;

      --  If choice is non-static, left operand is in non-static context

      if (Present (Choice) and then not Is_Static_Choice (Choice))
        or else (Present (Alts) and then not Is_Static_Choice_List (Alts))
      then
         Check_Non_Static_Context (Expr);
         return;
      end if;

      --  Otherwise we definitely have a static expression

      Set_Is_Static_Expression (N);

      --  If left operand raises Constraint_Error, propagate and we are done

      if Raises_Constraint_Error (Expr) then
         Set_Raises_Constraint_Error (N, True);

      --  See if we match

      else
         if Present (Choice) then
            Result := Choice_Matches (Expr, Choice);
         else
            Result := Choices_Match (Expr, Alts);
         end if;

         --  If result is Non_Static, it means that we raise Constraint_Error,
         --  since we already tested that the operands were themselves static.

         if Result = Non_Static then
            Set_Raises_Constraint_Error (N);

         --  Otherwise we have our result (flipped if NOT IN case)

         else
            Fold_Uint
              (N, Test (Result = Match xor Nkind (N) = N_Not_In), True);
            Warn_On_Known_Condition (N);
         end if;
      end if;
   end Eval_Membership_Op;

   ------------------------
   -- Eval_Named_Integer --
   ------------------------

   procedure Eval_Named_Integer (N : Node_Id) is
   begin
      Fold_Uint (N,
        Expr_Value (Expression (Declaration_Node (Entity (N)))), True);
   end Eval_Named_Integer;

   ---------------------
   -- Eval_Named_Real --
   ---------------------

   procedure Eval_Named_Real (N : Node_Id) is
   begin
      Fold_Ureal (N,
        Expr_Value_R (Expression (Declaration_Node (Entity (N)))), True);
   end Eval_Named_Real;

   -------------------
   -- Eval_Op_Expon --
   -------------------

   --  Exponentiation is a static functions, so the result is potentially
   --  static if both operands are potentially static (RM 4.9(7), 4.9(20)).

   procedure Eval_Op_Expon (N : Node_Id) is
      Left  : constant Node_Id := Left_Opnd (N);
      Right : constant Node_Id := Right_Opnd (N);
      Stat  : Boolean;
      Fold  : Boolean;

   begin
      --  If not foldable we are done

      Test_Expression_Is_Foldable
        (N, Left, Right, Stat, Fold, CRT_Safe => True);

      --  Return if not foldable

      if not Fold then
         return;
      end if;

      if Configurable_Run_Time_Mode and not Stat then
         return;
      end if;

      --  Fold exponentiation operation

      declare
         Right_Int : constant Uint := Expr_Value (Right);

      begin
         --  Integer case

         if Is_Integer_Type (Etype (Left)) then
            declare
               Left_Int : constant Uint := Expr_Value (Left);
               Result   : Uint;

            begin
               --  Exponentiation of an integer raises Constraint_Error for a
               --  negative exponent (RM 4.5.6).

               if Right_Int < 0 then
                  Apply_Compile_Time_Constraint_Error
                    (N, "integer exponent negative", CE_Range_Check_Failed,
                     Warn => not Stat);
                  return;

               else
                  if OK_Bits (N, Num_Bits (Left_Int) * Right_Int) then
                     Result := Left_Int ** Right_Int;
                  else
                     Result := Left_Int;
                  end if;

                  if Is_Modular_Integer_Type (Etype (N)) then
                     Result := Result mod Modulus (Etype (N));
                  end if;

                  Check_Non_Static_Context_For_Overflow (N, Stat, Result);

                  Fold_Uint (N, Result, Stat);
               end if;
            end;

         --  Real case

         else
            declare
               Left_Real : constant Ureal := Expr_Value_R (Left);

            begin
               --  Cannot have a zero base with a negative exponent

               if UR_Is_Zero (Left_Real) then

                  if Right_Int < 0 then
                     Apply_Compile_Time_Constraint_Error
                       (N, "zero ** negative integer", CE_Range_Check_Failed,
                        Warn => not Stat);
                     return;
                  else
                     Fold_Ureal (N, Ureal_0, Stat);
                  end if;

               else
                  Fold_Ureal (N, Left_Real ** Right_Int, Stat);
               end if;
            end;
         end if;
      end;
   end Eval_Op_Expon;

   -----------------
   -- Eval_Op_Not --
   -----------------

   --  The not operation is a static function, so the result is potentially
   --  static if the operand is potentially static (RM 4.9(7), 4.9(20)).

   procedure Eval_Op_Not (N : Node_Id) is
      Right : constant Node_Id := Right_Opnd (N);
      Stat  : Boolean;
      Fold  : Boolean;

   begin
      --  If not foldable we are done

      Test_Expression_Is_Foldable (N, Right, Stat, Fold);

      if not Fold then
         return;
      end if;

      --  Fold not operation

      declare
         Rint : constant Uint      := Expr_Value (Right);
         Typ  : constant Entity_Id := Etype (N);

      begin
         --  Negation is equivalent to subtracting from the modulus minus one.
         --  For a binary modulus this is equivalent to the ones-complement of
         --  the original value. For a nonbinary modulus this is an arbitrary
         --  but consistent definition.

         if Is_Modular_Integer_Type (Typ) then
            Fold_Uint (N, Modulus (Typ) - 1 - Rint, Stat);
         else pragma Assert (Is_Boolean_Type (Typ));
            Fold_Uint (N, Test (not Is_True (Rint)), Stat);
         end if;

         Set_Is_Static_Expression (N, Stat);
      end;
   end Eval_Op_Not;

   -------------------------------
   -- Eval_Qualified_Expression --
   -------------------------------

   --  A qualified expression is potentially static if its subtype mark denotes
   --  a static subtype and its expression is potentially static (RM 4.9 (10)).

   procedure Eval_Qualified_Expression (N : Node_Id) is
      Operand     : constant Node_Id   := Expression (N);
      Target_Type : constant Entity_Id := Entity (Subtype_Mark (N));

      Stat : Boolean;
      Fold : Boolean;
      Hex  : Boolean;

   begin
      --  Can only fold if target is string or scalar and subtype is static.
      --  Also, do not fold if our parent is an allocator (this is because the
      --  qualified expression is really part of the syntactic structure of an
      --  allocator, and we do not want to end up with something that
      --  corresponds to "new 1" where the 1 is the result of folding a
      --  qualified expression).

      if not Is_Static_Subtype (Target_Type)
        or else Nkind (Parent (N)) = N_Allocator
      then
         Check_Non_Static_Context (Operand);

         --  If operand is known to raise Constraint_Error, set the flag on the
         --  expression so it does not get optimized away.

         if Nkind (Operand) = N_Raise_Constraint_Error then
            Set_Raises_Constraint_Error (N);
         end if;

         return;

      --  Also return if a semantic error has been posted on the node, as we
      --  don't want to fold in that case (for GNATprove, the node might lead
      --  to Constraint_Error but won't have been replaced with a raise node
      --  or marked as raising CE).

      elsif Error_Posted (N) then
         return;
      end if;

      --  If not foldable we are done

      Test_Expression_Is_Foldable (N, Operand, Stat, Fold);

      if not Fold then
         return;

      --  Don't try fold if target type has Constraint_Error bounds

      elsif not Is_OK_Static_Subtype (Target_Type) then
         Set_Raises_Constraint_Error (N);
         return;
      end if;

      --  Fold the result of qualification

      if Is_Discrete_Type (Target_Type) then

         --  Save Print_In_Hex indication

         Hex := Nkind (Operand) = N_Integer_Literal
                  and then Print_In_Hex (Operand);

         Fold_Uint (N, Expr_Value (Operand), Stat);

         --  Preserve Print_In_Hex indication

         if Hex and then Nkind (N) = N_Integer_Literal then
            Set_Print_In_Hex (N);
         end if;

      elsif Is_Real_Type (Target_Type) then
         Fold_Ureal (N, Expr_Value_R (Operand), Stat);

      else
         Fold_Str (N, Strval (Get_String_Val (Operand)), Stat);

         if not Stat then
            Set_Is_Static_Expression (N, False);
         else
            Check_String_Literal_Length (N, Target_Type);
         end if;

         return;
      end if;

      --  The expression may be foldable but not static

      Set_Is_Static_Expression (N, Stat);

      if Is_Out_Of_Range (N, Etype (N), Assume_Valid => True) then
         Out_Of_Range (N);
      end if;
   end Eval_Qualified_Expression;

   -----------------------
   -- Eval_Real_Literal --
   -----------------------

   --  Numeric literals are static (RM 4.9(1)), and have already been marked
   --  as static by the analyzer. The reason we did it that early is to allow
   --  the possibility of turning off the Is_Static_Expression flag after
   --  analysis, but before resolution, when integer literals are generated
   --  in the expander that do not correspond to static expressions.

   procedure Eval_Real_Literal (N : Node_Id) is
      PK : constant Node_Kind := Nkind (Parent (N));

   begin
      --  If the literal appears in a non-expression context and not as part of
      --  a number declaration, then it is appearing in a non-static context,
      --  so check it.

      if PK not in N_Subexpr and then PK /= N_Number_Declaration then
         Check_Non_Static_Context (N);
      end if;
   end Eval_Real_Literal;

   ------------------------
   -- Eval_Relational_Op --
   ------------------------

   --  Relational operations are static functions, so the result is static if
   --  both operands are static (RM 4.9(7), 4.9(20)), except that up to Ada
   --  2012, for strings the result is never static, even if the operands are.
   --  The string case was relaxed in Ada 2022, see AI12-0201.

   --  However, for internally generated nodes, we allow string equality and
   --  inequality to be static. This is because we rewrite A in "ABC" as an
   --  equality test A = "ABC", and the former is definitely static.

   procedure Eval_Relational_Op (N : Node_Id) is
      Left  : constant Node_Id := Left_Opnd  (N);
      Right : constant Node_Id := Right_Opnd (N);

      procedure Decompose_Expr
        (Expr : Node_Id;
         Ent  : out Entity_Id;
         Kind : out Character;
         Cons : out Uint;
         Orig : Boolean := True);
      --  Given expression Expr, see if it is of the form X [+/- K]. If so, Ent
      --  is set to the entity in X, Kind is 'F','L','E' for 'First or 'Last or
      --  simple entity, and Cons is the value of K. If the expression is not
      --  of the required form, Ent is set to Empty.
      --
      --  Orig indicates whether Expr is the original expression to consider,
      --  or if we are handling a subexpression (e.g. recursive call to
      --  Decompose_Expr).

      procedure Fold_General_Op (Is_Static : Boolean);
      --  Attempt to fold arbitrary relational operator N. Flag Is_Static must
      --  be set when the operator denotes a static expression.

      procedure Fold_Static_Real_Op;
      --  Attempt to fold static real type relational operator N

      function Static_Length (Expr : Node_Id) return Uint;
      --  If Expr is an expression for a constrained array whose length is
      --  known at compile time, return the non-negative length, otherwise
      --  return -1.

      --------------------
      -- Decompose_Expr --
      --------------------

      procedure Decompose_Expr
        (Expr : Node_Id;
         Ent  : out Entity_Id;
         Kind : out Character;
         Cons : out Uint;
         Orig : Boolean := True)
      is
         Exp : Node_Id;

      begin
         --  Assume that the expression does not meet the expected form

         Cons := No_Uint;
         Ent  := Empty;
         Kind := '?';

         if Nkind (Expr) = N_Op_Add
           and then Compile_Time_Known_Value (Right_Opnd (Expr))
         then
            Exp  := Left_Opnd (Expr);
            Cons := Expr_Value (Right_Opnd (Expr));

         elsif Nkind (Expr) = N_Op_Subtract
           and then Compile_Time_Known_Value (Right_Opnd (Expr))
         then
            Exp  := Left_Opnd (Expr);
            Cons := -Expr_Value (Right_Opnd (Expr));

         --  If the bound is a constant created to remove side effects, recover
         --  the original expression to see if it has one of the recognizable
         --  forms.

         elsif Nkind (Expr) = N_Identifier
           and then not Comes_From_Source (Entity (Expr))
           and then Ekind (Entity (Expr)) = E_Constant
           and then Nkind (Parent (Entity (Expr))) = N_Object_Declaration
         then
            Exp := Expression (Parent (Entity (Expr)));
            Decompose_Expr (Exp, Ent, Kind, Cons, Orig => False);

            --  If original expression includes an entity, create a reference
            --  to it for use below.

            if Present (Ent) then
               Exp := New_Occurrence_Of (Ent, Sloc (Ent));
            else
               return;
            end if;

         else
            --  Only consider the case of X + 0 for a full expression, and
            --  not when recursing, otherwise we may end up with evaluating
            --  expressions not known at compile time to 0.

            if Orig then
               Exp  := Expr;
               Cons := Uint_0;
            else
               return;
            end if;
         end if;

         --  At this stage Exp is set to the potential X

         if Nkind (Exp) = N_Attribute_Reference then
            if Attribute_Name (Exp) = Name_First then
               Kind := 'F';
            elsif Attribute_Name (Exp) = Name_Last then
               Kind := 'L';
            else
               return;
            end if;

            Exp := Prefix (Exp);

         else
            Kind := 'E';
         end if;

         if Is_Entity_Name (Exp) and then Present (Entity (Exp)) then
            Ent := Entity (Exp);
         end if;
      end Decompose_Expr;

      ---------------------
      -- Fold_General_Op --
      ---------------------

      procedure Fold_General_Op (Is_Static : Boolean) is
         CR : constant Compare_Result :=
                Compile_Time_Compare (Left, Right, Assume_Valid => False);

         Result : Boolean;

      begin
         if CR = Unknown then
            return;
         end if;

         case Nkind (N) is
            when N_Op_Eq =>
               if CR = EQ then
                  Result := True;
               elsif CR = NE or else CR = GT or else CR = LT then
                  Result := False;
               else
                  return;
               end if;

            when N_Op_Ge =>
               if CR = GT or else CR = EQ or else CR = GE then
                  Result := True;
               elsif CR = LT then
                  Result := False;
               else
                  return;
               end if;

            when N_Op_Gt =>
               if CR = GT then
                  Result := True;
               elsif CR = EQ or else CR = LT or else CR = LE then
                  Result := False;
               else
                  return;
               end if;

            when N_Op_Le =>
               if CR = LT or else CR = EQ or else CR = LE then
                  Result := True;
               elsif CR = GT then
                  Result := False;
               else
                  return;
               end if;

            when N_Op_Lt =>
               if CR = LT then
                  Result := True;
               elsif CR = EQ or else CR = GT or else CR = GE then
                  Result := False;
               else
                  return;
               end if;

            when N_Op_Ne =>
               if CR = NE or else CR = GT or else CR = LT then
                  Result := True;
               elsif CR = EQ then
                  Result := False;
               else
                  return;
               end if;

            when others =>
               raise Program_Error;
         end case;

         --  Determine the potential outcome of the relation assuming the
         --  operands are valid and emit a warning when the relation yields
         --  True or False only in the presence of invalid values.

         Warn_On_Constant_Valid_Condition (N);

         Fold_Uint (N, Test (Result), Is_Static);
      end Fold_General_Op;

      -------------------------
      -- Fold_Static_Real_Op --
      -------------------------

      procedure Fold_Static_Real_Op is
         Left_Real  : constant Ureal := Expr_Value_R (Left);
         Right_Real : constant Ureal := Expr_Value_R (Right);
         Result     : Boolean;

      begin
         case Nkind (N) is
            when N_Op_Eq => Result := (Left_Real =  Right_Real);
            when N_Op_Ge => Result := (Left_Real >= Right_Real);
            when N_Op_Gt => Result := (Left_Real >  Right_Real);
            when N_Op_Le => Result := (Left_Real <= Right_Real);
            when N_Op_Lt => Result := (Left_Real <  Right_Real);
            when N_Op_Ne => Result := (Left_Real /= Right_Real);
            when others  => raise Program_Error;
         end case;

         Fold_Uint (N, Test (Result), True);
      end Fold_Static_Real_Op;

      -------------------
      -- Static_Length --
      -------------------

      function Static_Length (Expr : Node_Id) return Uint is
         Cons1 : Uint;
         Cons2 : Uint;
         Ent1  : Entity_Id;
         Ent2  : Entity_Id;
         Kind1 : Character;
         Kind2 : Character;
         Typ   : Entity_Id;

      begin
         --  First easy case string literal

         if Nkind (Expr) = N_String_Literal then
            return UI_From_Int (String_Length (Strval (Expr)));

         --  With frontend inlining as performed in GNATprove mode, a variable
         --  may be inserted that has a string literal subtype. Deal with this
         --  specially as for the previous case.

         elsif Ekind (Etype (Expr)) = E_String_Literal_Subtype then
            return String_Literal_Length (Etype (Expr));

         --  Second easy case, not constrained subtype, so no length

         elsif not Is_Constrained (Etype (Expr)) then
            return Uint_Minus_1;
         end if;

         --  General case

         Typ := Etype (First_Index (Etype (Expr)));

         --  The simple case, both bounds are known at compile time

         if Is_Discrete_Type (Typ)
           and then Compile_Time_Known_Value (Type_Low_Bound (Typ))
           and then Compile_Time_Known_Value (Type_High_Bound (Typ))
         then
            return
              UI_Max (Uint_0, Expr_Value (Type_High_Bound (Typ)) -
                              Expr_Value (Type_Low_Bound  (Typ)) + 1);
         end if;

         --  A more complex case, where the bounds are of the form X [+/- K1]
         --  .. X [+/- K2]), where X is an expression that is either A'First or
         --  A'Last (with A an entity name), or X is an entity name, and the
         --  two X's are the same and K1 and K2 are known at compile time, in
         --  this case, the length can also be computed at compile time, even
         --  though the bounds are not known. A common case of this is e.g.
         --  (X'First .. X'First+5).

         Decompose_Expr
           (Original_Node (Type_Low_Bound  (Typ)), Ent1, Kind1, Cons1);
         Decompose_Expr
           (Original_Node (Type_High_Bound (Typ)), Ent2, Kind2, Cons2);

         if Present (Ent1) and then Ent1 = Ent2 and then Kind1 = Kind2 then
            return Cons2 - Cons1 + 1;
         else
            return Uint_Minus_1;
         end if;
      end Static_Length;

      --  Local variables

      Left_Typ  : constant Entity_Id := Etype (Left);
      Right_Typ : constant Entity_Id := Etype (Right);
      Fold      : Boolean;
      Left_Len  : Uint;
      Op_Typ    : Entity_Id := Empty;
      Right_Len : Uint;

      Is_Static_Expression : Boolean;

   --  Start of processing for Eval_Relational_Op

   begin
      --  One special case to deal with first. If we can tell that the result
      --  will be false because the lengths of one or more index subtypes are
      --  compile-time known and different, then we can replace the entire
      --  result by False. We only do this for one-dimensional arrays, because
      --  the case of multidimensional arrays is rare and too much trouble. If
      --  one of the operands is an illegal aggregate, its type might still be
      --  an arbitrary composite type, so nothing to do.

      if Is_Array_Type (Left_Typ)
        and then Left_Typ /= Any_Composite
        and then Number_Dimensions (Left_Typ) = 1
        and then Nkind (N) in N_Op_Eq | N_Op_Ne
      then
         if Raises_Constraint_Error (Left)
              or else
            Raises_Constraint_Error (Right)
         then
            return;
         end if;

         --  OK, we have the case where we may be able to do this fold

         Left_Len  := Static_Length (Left);
         Right_Len := Static_Length (Right);

         if Left_Len /= Uint_Minus_1
           and then Right_Len /= Uint_Minus_1
           and then Left_Len /= Right_Len
         then
            --  AI12-0201: comparison of string is static in Ada 2022

            Fold_Uint
              (N,
               Test (Nkind (N) = N_Op_Ne),
               Static => Ada_Version >= Ada_2022
                           and then Is_String_Type (Left_Typ));
            Warn_On_Known_Condition (N);
            return;
         end if;
      end if;

      --  General case

      --  Initialize the value of Is_Static_Expression. The value of Fold
      --  returned by Test_Expression_Is_Foldable is not needed since, even
      --  when some operand is a variable, we can still perform the static
      --  evaluation of the expression in some cases (for example, for a
      --  variable of a subtype of Integer we statically know that any value
      --  stored in such variable is smaller than Integer'Last).

      Test_Expression_Is_Foldable
        (N, Left, Right, Is_Static_Expression, Fold);

      --  Comparisons of scalars can give static results.
      --  In addition starting with Ada 2022 (AI12-0201), comparison of strings
      --  can also give static results, and as noted above, we also allow for
      --  earlier Ada versions internally generated equality and inequality for
      --  strings.
      --  The Comes_From_Source test below isn't correct and will accept
      --  some cases that are illegal in Ada 2012 and before. Now that Ada
      --  2022 has relaxed the rules, this doesn't really matter.

      if Is_String_Type (Left_Typ) then
         if Ada_Version < Ada_2022
           and then (Comes_From_Source (N)
                      or else Nkind (N) not in N_Op_Eq | N_Op_Ne)
         then
            Is_Static_Expression := False;
            Set_Is_Static_Expression (N, False);
         end if;

      elsif not Is_Scalar_Type (Left_Typ) then
         Is_Static_Expression := False;
         Set_Is_Static_Expression (N, False);
      end if;

      --  For operators on universal numeric types called as functions with an
      --  explicit scope, determine appropriate specific numeric type, and
      --  diagnose possible ambiguity.

      if Is_Universal_Numeric_Type (Left_Typ)
           and then
         Is_Universal_Numeric_Type (Right_Typ)
      then
         Op_Typ := Find_Universal_Operator_Type (N);
      end if;

      --  Attempt to fold the relational operator

      if Is_Static_Expression and then Is_Real_Type (Left_Typ) then
         Fold_Static_Real_Op;
      else
         Fold_General_Op (Is_Static_Expression);
      end if;

      --  For the case of a folded relational operator on a specific numeric
      --  type, freeze the operand type now.

      if Present (Op_Typ) then
         Freeze_Before (N, Op_Typ);
      end if;

      Warn_On_Known_Condition (N);
   end Eval_Relational_Op;

   -----------------------------
   -- Eval_Selected_Component --
   -----------------------------

   procedure Eval_Selected_Component (N : Node_Id) is
      Node : Node_Id;
      Comp : Node_Id;
      C    : Node_Id;
      Nam  : Name_Id;

   begin
      --  If an attribute reference or a LHS, nothing to do.
      --  Also do not fold if N is an [in] out subprogram parameter.
      --  Fold will perform the other relevant tests.

      if Nkind (Parent (N)) /= N_Attribute_Reference
        and then not Known_To_Be_Assigned (N)
        and then not Is_Actual_Out_Or_In_Out_Parameter (N)
      then
         --  Simplify a selected_component on an aggregate by extracting
         --  the field directly.

         Node := Unqualify (Prefix (N));

         if Nkind (Node) = N_Aggregate
           and then Compile_Time_Known_Aggregate (Node)
         then
            Comp := First (Component_Associations (Node));
            Nam  := Chars (Selector_Name (N));

            while Present (Comp) loop
               C := First (Choices (Comp));

               while Present (C) loop
                  if Chars (C) = Nam then
                     Rewrite (N, Relocate_Node (Expression (Comp)));
                     return;
                  end if;

                  Next (C);
               end loop;

               Next (Comp);
            end loop;
         else
            Fold (N);
         end if;
      end if;
   end Eval_Selected_Component;

   ----------------
   -- Eval_Shift --
   ----------------

   procedure Eval_Shift (N : Node_Id) is
   begin
      --  This procedure is only called for compiler generated code (e.g.
      --  packed arrays), so there is nothing to do except attempting to fold
      --  the expression.

      Fold_Shift (N, Left_Opnd (N), Right_Opnd (N), Nkind (N));
   end Eval_Shift;

   ------------------------
   -- Eval_Short_Circuit --
   ------------------------

   --  A short circuit operation is potentially static if both operands are
   --  potentially static (RM 4.9 (13)).

   procedure Eval_Short_Circuit (N : Node_Id) is
      Kind     : constant Node_Kind := Nkind (N);
      Left     : constant Node_Id   := Left_Opnd (N);
      Right    : constant Node_Id   := Right_Opnd (N);
      Left_Int : Uint;

      Rstat : constant Boolean :=
                Is_Static_Expression (Left)
                  and then
                Is_Static_Expression (Right);

   begin
      --  Short circuit operations are never static in Ada 83

      if Ada_Version = Ada_83 and then Comes_From_Source (N) then
         Check_Non_Static_Context (Left);
         Check_Non_Static_Context (Right);
         return;
      end if;

      --  Now look at the operands, we can't quite use the normal call to
      --  Test_Expression_Is_Foldable here because short circuit operations
      --  are a special case, they can still be foldable, even if the right
      --  operand raises Constraint_Error.

      --  If either operand is Any_Type, just propagate to result and do not
      --  try to fold, this prevents cascaded errors.

      if Etype (Left) = Any_Type or else Etype (Right) = Any_Type then
         Set_Etype (N, Any_Type);
         return;

      --  If left operand raises Constraint_Error, then replace node N with
      --  the raise Constraint_Error node, and we are obviously not foldable.
      --  Is_Static_Expression is set from the two operands in the normal way,
      --  and we check the right operand if it is in a non-static context.

      elsif Raises_Constraint_Error (Left) then
         if not Rstat then
            Check_Non_Static_Context (Right);
         end if;

         Rewrite_In_Raise_CE (N, Left);
         Set_Is_Static_Expression (N, Rstat);
         return;

      --  If the result is not static, then we won't in any case fold

      elsif not Rstat then
         Check_Non_Static_Context (Left);
         Check_Non_Static_Context (Right);
         return;
      end if;

      --  Here the result is static, note that, unlike the normal processing
      --  in Test_Expression_Is_Foldable, we did *not* check above to see if
      --  the right operand raises Constraint_Error, that's because it is not
      --  significant if the left operand is decisive.

      Set_Is_Static_Expression (N);

      --  It does not matter if the right operand raises Constraint_Error if
      --  it will not be evaluated. So deal specially with the cases where
      --  the right operand is not evaluated. Note that we will fold these
      --  cases even if the right operand is non-static, which is fine, but
      --  of course in these cases the result is not potentially static.

      Left_Int := Expr_Value (Left);

      if (Kind = N_And_Then and then Is_False (Left_Int))
           or else
         (Kind = N_Or_Else  and then Is_True  (Left_Int))
      then
         Fold_Uint (N, Left_Int, Rstat);
         return;
      end if;

      --  If first operand not decisive, then it does matter if the right
      --  operand raises Constraint_Error, since it will be evaluated, so
      --  we simply replace the node with the right operand. Note that this
      --  properly propagates Is_Static_Expression and Raises_Constraint_Error
      --  (both are set to True in Right).

      if Raises_Constraint_Error (Right) then
         Rewrite_In_Raise_CE (N, Right);
         Check_Non_Static_Context (Left);
         return;
      end if;

      --  Otherwise the result depends on the right operand

      Fold_Uint (N, Expr_Value (Right), Rstat);
      return;
   end Eval_Short_Circuit;

   ----------------
   -- Eval_Slice --
   ----------------

   --  Slices can never be static, so the only processing required is to check
   --  for non-static context if an explicit range is given.

   procedure Eval_Slice (N : Node_Id) is
      Drange : constant Node_Id := Discrete_Range (N);
      Name   : constant Node_Id := Prefix (N);

   begin
      if Nkind (Drange) = N_Range then
         Check_Non_Static_Context (Low_Bound (Drange));
         Check_Non_Static_Context (High_Bound (Drange));
      end if;

      --  A slice of the form A (subtype), when the subtype is the index of
      --  the type of A, is redundant, the slice can be replaced with A, and
      --  this is worth a warning.

      if Is_Entity_Name (Name) then
         declare
            E : constant Entity_Id := Entity (Name);
            T : constant Entity_Id := Etype (E);

         begin
            if Is_Object (E)
              and then Is_Array_Type (T)
              and then Is_Entity_Name (Drange)
            then
               if Is_Entity_Name (Original_Node (First_Index (T)))
                 and then Entity (Original_Node (First_Index (T)))
                    = Entity (Drange)
               then
                  if Warn_On_Redundant_Constructs then
                     Error_Msg_N ("redundant slice denotes whole array?r?", N);
                  end if;

                  --  The following might be a useful optimization???

                  --  Rewrite (N, New_Occurrence_Of (E, Sloc (N)));
               end if;
            end if;
         end;
      end if;
   end Eval_Slice;

   -------------------------
   -- Eval_String_Literal --
   -------------------------

   procedure Eval_String_Literal (N : Node_Id) is
      Typ : constant Entity_Id := Etype (N);
      Bas : constant Entity_Id := Base_Type (Typ);
      Xtp : Entity_Id;
      Len : Nat;
      Lo  : Node_Id;

   begin
      --  Nothing to do if error type (handles cases like default expressions
      --  or generics where we have not yet fully resolved the type).

      if Bas = Any_Type or else Bas = Any_String then
         return;
      end if;

      --  String literals are static if the subtype is static (RM 4.9(2)), so
      --  reset the static expression flag (it was set unconditionally in
      --  Analyze_String_Literal) if the subtype is non-static. We tell if
      --  the subtype is static by looking at the lower bound.

      if Ekind (Typ) = E_String_Literal_Subtype then
         if not Is_OK_Static_Expression (String_Literal_Low_Bound (Typ)) then
            Set_Is_Static_Expression (N, False);
            return;
         end if;

      --  Here if Etype of string literal is normal Etype (not yet possible,
      --  but may be possible in future).

      elsif not Is_OK_Static_Expression
                  (Type_Low_Bound (Etype (First_Index (Typ))))
      then
         Set_Is_Static_Expression (N, False);
         return;
      end if;

      --  If original node was a type conversion, then result if non-static
      --  up to Ada 2012. AI12-0201 changes that with Ada 2022.

      if Nkind (Original_Node (N)) = N_Type_Conversion
        and then Ada_Version <= Ada_2012
      then
         Set_Is_Static_Expression (N, False);
         return;
      end if;

      --  Test for illegal Ada 95 cases. A string literal is illegal in Ada 95
      --  if its bounds are outside the index base type and this index type is
      --  static. This can happen in only two ways. Either the string literal
      --  is too long, or it is null, and the lower bound is type'First. Either
      --  way it is the upper bound that is out of range of the index type.

      if Ada_Version >= Ada_95 then
         if Is_Standard_String_Type (Bas) then
            Xtp := Standard_Positive;
         else
            Xtp := Etype (First_Index (Bas));
         end if;

         if Ekind (Typ) = E_String_Literal_Subtype then
            Lo := String_Literal_Low_Bound (Typ);
         else
            Lo := Type_Low_Bound (Etype (First_Index (Typ)));
         end if;

         --  Check for string too long

         Len := String_Length (Strval (N));

         if Len > String_Type_Len (Bas) then

            --  Issue message. Note that this message is a warning if the
            --  string literal is not marked as static (happens in some cases
            --  of folding strings known at compile time, but not static).
            --  Furthermore in such cases, we reword the message, since there
            --  is no string literal in the source program.

            if Is_Static_Expression (N) then
               Apply_Compile_Time_Constraint_Error
                 (N, "string literal too long for}", CE_Length_Check_Failed,
                  Ent => Bas,
                  Typ => First_Subtype (Bas));
            else
               Apply_Compile_Time_Constraint_Error
                 (N, "string value too long for}", CE_Length_Check_Failed,
                  Ent  => Bas,
                  Typ  => First_Subtype (Bas),
                  Warn => True);
            end if;

         --  Test for null string not allowed

         elsif Len = 0
           and then not Is_Generic_Type (Xtp)
           and then
             Expr_Value (Lo) = Expr_Value (Type_Low_Bound (Base_Type (Xtp)))
         then
            --  Same specialization of message

            if Is_Static_Expression (N) then
               Apply_Compile_Time_Constraint_Error
                 (N, "null string literal not allowed for}",
                  CE_Length_Check_Failed,
                  Ent => Bas,
                  Typ => First_Subtype (Bas));
            else
               Apply_Compile_Time_Constraint_Error
                 (N, "null string value not allowed for}",
                  CE_Length_Check_Failed,
                  Ent  => Bas,
                  Typ  => First_Subtype (Bas),
                  Warn => True);
            end if;
         end if;
      end if;
   end Eval_String_Literal;

   --------------------------
   -- Eval_Type_Conversion --
   --------------------------

   --  A type conversion is potentially static if its subtype mark is for a
   --  static scalar subtype, and its operand expression is potentially static
   --  (RM 4.9(10)).
   --  Also add support for static string types.

   procedure Eval_Type_Conversion (N : Node_Id) is
      Operand     : constant Node_Id   := Expression (N);
      Source_Type : constant Entity_Id := Etype (Operand);
      Target_Type : constant Entity_Id := Etype (N);

      function To_Be_Treated_As_Integer (T : Entity_Id) return Boolean;
      --  Returns true if type T is an integer type, or if it is a fixed-point
      --  type to be treated as an integer (i.e. the flag Conversion_OK is set
      --  on the conversion node).

      function To_Be_Treated_As_Real (T : Entity_Id) return Boolean;
      --  Returns true if type T is a floating-point type, or if it is a
      --  fixed-point type that is not to be treated as an integer (i.e. the
      --  flag Conversion_OK is not set on the conversion node).

      ------------------------------
      -- To_Be_Treated_As_Integer --
      ------------------------------

      function To_Be_Treated_As_Integer (T : Entity_Id) return Boolean is
      begin
         return
           Is_Integer_Type (T)
             or else (Is_Fixed_Point_Type (T) and then Conversion_OK (N));
      end To_Be_Treated_As_Integer;

      ---------------------------
      -- To_Be_Treated_As_Real --
      ---------------------------

      function To_Be_Treated_As_Real (T : Entity_Id) return Boolean is
      begin
         return
           Is_Floating_Point_Type (T)
             or else (Is_Fixed_Point_Type (T) and then not Conversion_OK (N));
      end To_Be_Treated_As_Real;

      --  Local variables

      Fold : Boolean;
      Stat : Boolean;

   --  Start of processing for Eval_Type_Conversion

   begin
      --  Cannot fold if target type is non-static or if semantic error

      if not Is_Static_Subtype (Target_Type) then
         Check_Non_Static_Context (Operand);
         return;
      elsif Error_Posted (N) then
         return;
      end if;

      --  If not foldable we are done

      Test_Expression_Is_Foldable (N, Operand, Stat, Fold);

      if not Fold then
         return;

      --  Don't try fold if target type has Constraint_Error bounds

      elsif not Is_OK_Static_Subtype (Target_Type) then
         Set_Raises_Constraint_Error (N);
         return;
      end if;

      --  Remaining processing depends on operand types. Note that in the
      --  following type test, fixed-point counts as real unless the flag
      --  Conversion_OK is set, in which case it counts as integer.

      --  Fold conversion, case of string type. The result is static starting
      --  with Ada 2022 (AI12-0201).

      if Is_String_Type (Target_Type) then
         Fold_Str
           (N,
            Strval (Get_String_Val (Operand)),
            Static => Ada_Version >= Ada_2022);
         return;

      --  Fold conversion, case of integer target type

      elsif To_Be_Treated_As_Integer (Target_Type) then
         declare
            Result : Uint;

         begin
            --  Integer to integer conversion

            if To_Be_Treated_As_Integer (Source_Type) then
               Result := Expr_Value (Operand);

            --  Real to integer conversion

            elsif To_Be_Treated_As_Real (Source_Type) then
               Result := UR_To_Uint (Expr_Value_R (Operand));

            --  Enumeration to integer conversion, aka 'Enum_Rep

            else
               Result := Expr_Rep_Value (Operand);
            end if;

            --  If fixed-point type (Conversion_OK must be set), then the
            --  result is logically an integer, but we must replace the
            --  conversion with the corresponding real literal, since the
            --  type from a semantic point of view is still fixed-point.

            if Is_Fixed_Point_Type (Target_Type) then
               Fold_Ureal
                 (N, UR_From_Uint (Result) * Small_Value (Target_Type), Stat);

            --  Otherwise result is integer literal

            else
               Fold_Uint (N, Result, Stat);
            end if;
         end;

      --  Fold conversion, case of real target type

      elsif To_Be_Treated_As_Real (Target_Type) then
         declare
            Result : Ureal;

         begin
            if To_Be_Treated_As_Real (Source_Type) then
               Result := Expr_Value_R (Operand);
            else
               Result := UR_From_Uint (Expr_Value (Operand));
            end if;

            Fold_Ureal (N, Result, Stat);
         end;

      --  Enumeration types

      else
         Fold_Uint (N, Expr_Value (Operand), Stat);
      end if;

      --  If the target is a static floating-point subtype, then its bounds
      --  are machine numbers so we must consider the machine-rounded value.

      if Is_Floating_Point_Type (Target_Type)
        and then Nkind (N) = N_Real_Literal
        and then not Is_Machine_Number (N)
      then
         declare
            Lo   : constant Node_Id := Type_Low_Bound (Target_Type);
            Hi   : constant Node_Id := Type_High_Bound (Target_Type);
            Valr : constant Ureal   :=
                     Machine_Number (Target_Type, Expr_Value_R (N), N);
         begin
            if Valr < Expr_Value_R (Lo) or else Valr > Expr_Value_R (Hi) then
               Out_Of_Range (N);
            end if;
         end;

      elsif Is_Out_Of_Range (N, Etype (N), Assume_Valid => True) then
         Out_Of_Range (N);
      end if;
   end Eval_Type_Conversion;

   -------------------
   -- Eval_Unary_Op --
   -------------------

   --  Predefined unary operators are static functions (RM 4.9(20)) and thus
   --  are potentially static if the operand is potentially static (RM 4.9(7)).

   procedure Eval_Unary_Op (N : Node_Id) is
      Right : constant Node_Id := Right_Opnd (N);
      Otype : Entity_Id := Empty;
      Stat  : Boolean;
      Fold  : Boolean;

   begin
      --  If not foldable we are done

      Test_Expression_Is_Foldable (N, Right, Stat, Fold);

      if not Fold then
         return;
      end if;

      if Is_Universal_Numeric_Type (Etype (Right)) then
         Otype := Find_Universal_Operator_Type (N);
      end if;

      --  Fold for integer case

      if Is_Integer_Type (Etype (N)) then
         declare
            Rint   : constant Uint := Expr_Value (Right);
            Result : Uint;

         begin
            --  In the case of modular unary plus and abs there is no need
            --  to adjust the result of the operation since if the original
            --  operand was in bounds the result will be in the bounds of the
            --  modular type. However, in the case of modular unary minus the
            --  result may go out of the bounds of the modular type and needs
            --  adjustment.

            if Nkind (N) = N_Op_Plus then
               Result := Rint;

            elsif Nkind (N) = N_Op_Minus then
               if Is_Modular_Integer_Type (Etype (N)) then
                  Result := (-Rint) mod Modulus (Etype (N));
               else
                  Result := (-Rint);
               end if;

            else
               pragma Assert (Nkind (N) = N_Op_Abs);
               Result := abs Rint;
            end if;

            Check_Non_Static_Context_For_Overflow (N, Stat, Result);

            Fold_Uint (N, Result, Stat);
         end;

      --  Fold for real case

      elsif Is_Real_Type (Etype (N)) then
         declare
            Rreal  : constant Ureal := Expr_Value_R (Right);
            Result : Ureal;

         begin
            if Nkind (N) = N_Op_Plus then
               Result := Rreal;
            elsif Nkind (N) = N_Op_Minus then
               Result := UR_Negate (Rreal);
            else
               pragma Assert (Nkind (N) = N_Op_Abs);
               Result := abs Rreal;
            end if;

            Fold_Ureal (N, Result, Stat);
         end;
      end if;

      --  If the operator was resolved to a specific type, make sure that type
      --  is frozen even if the expression is folded into a literal (which has
      --  a universal type).

      if Present (Otype) then
         Freeze_Before (N, Otype);
      end if;
   end Eval_Unary_Op;

   -------------------------------
   -- Eval_Unchecked_Conversion --
   -------------------------------

   --  Unchecked conversions can never be static, so the only required
   --  processing is to check for a non-static context for the operand.

   procedure Eval_Unchecked_Conversion (N : Node_Id) is
      Target_Type  : constant Entity_Id := Etype (N);
      Operand      : constant Node_Id   := Expression (N);
      Operand_Type : constant Entity_Id := Etype (Operand);

   begin
      Check_Non_Static_Context (Operand);

      --  If we have a conversion of a compile time known value to a target
      --  type and the value is in range of the target type, then we can simply
      --  replace the construct by an integer literal of the correct type. We
      --  only apply this to discrete types being converted. Possibly it may
      --  apply in other cases, but it is too much trouble to worry about.

      --  Note that we do not do this transformation if the Kill_Range_Check
      --  flag is set, since then the value may be outside the expected range.
      --  This happens in the Normalize_Scalars case.

      --  We also skip this if either the target or operand type is biased
      --  because in this case, the unchecked conversion is supposed to
      --  preserve the bit pattern, not the integer value.

      if Is_Integer_Type (Target_Type)
        and then not Has_Biased_Representation (Target_Type)
        and then Is_Discrete_Type (Operand_Type)
        and then not Has_Biased_Representation (Operand_Type)
        and then Compile_Time_Known_Value (Operand)
        and then not Kill_Range_Check (N)
      then
         declare
            Val : constant Uint := Expr_Rep_Value (Operand);

         begin
            if Compile_Time_Known_Value (Type_Low_Bound (Target_Type))
                 and then
               Compile_Time_Known_Value (Type_High_Bound (Target_Type))
                 and then
               Val >= Expr_Value (Type_Low_Bound (Target_Type))
                 and then
               Val <= Expr_Value (Type_High_Bound (Target_Type))
            then
               Rewrite (N, Make_Integer_Literal (Sloc (N), Val));

               --  If Address is the target type, just set the type to avoid a
               --  spurious type error on the literal when Address is a visible
               --  integer type.

               if Is_Descendant_Of_Address (Target_Type) then
                  Set_Etype (N, Target_Type);
               else
                  Analyze_And_Resolve (N, Target_Type);
               end if;

               return;
            end if;
         end;
      end if;
   end Eval_Unchecked_Conversion;

   --------------------
   -- Expr_Rep_Value --
   --------------------

   function Expr_Rep_Value (N : Node_Id) return Uint is
      Kind : constant Node_Kind := Nkind (N);
      Ent  : Entity_Id;

   begin
      if Is_Entity_Name (N) then
         Ent := Entity (N);

         --  An enumeration literal that was either in the source or created
         --  as a result of static evaluation.

         if Ekind (Ent) = E_Enumeration_Literal then
            return Enumeration_Rep (Ent);

         --  A user defined static constant

         else
            pragma Assert (Ekind (Ent) = E_Constant);
            return Expr_Rep_Value (Constant_Value (Ent));
         end if;

      --  An integer literal that was either in the source or created as a
      --  result of static evaluation.

      elsif Kind = N_Integer_Literal then
         return Intval (N);

      --  A real literal for a fixed-point type. This must be the fixed-point
      --  case, either the literal is of a fixed-point type, or it is a bound
      --  of a fixed-point type, with type universal real. In either case we
      --  obtain the desired value from Corresponding_Integer_Value.

      elsif Kind = N_Real_Literal then
         pragma Assert (Is_Fixed_Point_Type (Underlying_Type (Etype (N))));
         return Corresponding_Integer_Value (N);

      --  The NULL access value

      elsif Kind = N_Null then
         pragma Assert (Is_Access_Type (Underlying_Type (Etype (N)))
           or else Error_Posted (N));
         return Uint_0;

      --  Character literal

      elsif Kind = N_Character_Literal then
         Ent := Entity (N);

         --  Since Character literals of type Standard.Character don't have any
         --  defining character literals built for them, they do not have their
         --  Entity set, so just use their Char code. Otherwise for user-
         --  defined character literals use their Pos value as usual which is
         --  the same as the Rep value.

         if No (Ent) then
            return Char_Literal_Value (N);
         else
            return Enumeration_Rep (Ent);
         end if;

      --  Unchecked conversion, which can come from System'To_Address (X)
      --  where X is a static integer expression. Recursively evaluate X.

      elsif Kind = N_Unchecked_Type_Conversion then
         return Expr_Rep_Value (Expression (N));

      --  Static discriminant value

      elsif Is_Static_Discriminant_Component (N) then
         return Expr_Rep_Value
                  (Get_Discriminant_Value
                     (Entity (Selector_Name (N)),
                      Etype (Prefix (N)),
                      Discriminant_Constraint (Etype (Prefix (N)))));

      else
         raise Program_Error;
      end if;
   end Expr_Rep_Value;

   ----------------
   -- Expr_Value --
   ----------------

   function Expr_Value (N : Node_Id) return Uint is
      Kind   : constant Node_Kind := Nkind (N);
      CV_Ent : CV_Entry renames CV_Cache (Nat (N) mod CV_Cache_Size);
      Ent    : Entity_Id;
      Val    : Uint;

   begin
      --  If already in cache, then we know it's compile-time-known and we can
      --  return the value that was previously stored in the cache since
      --  compile-time-known values cannot change.

      if CV_Ent.N = N then
         return CV_Ent.V;
      end if;

      --  Otherwise proceed to test value

      if Is_Entity_Name (N) then
         Ent := Entity (N);

         --  An enumeration literal that was either in the source or created as
         --  a result of static evaluation.

         if Ekind (Ent) = E_Enumeration_Literal then
            Val := Enumeration_Pos (Ent);

         --  A user defined static constant

         else
            pragma Assert (Ekind (Ent) = E_Constant);
            Val := Expr_Value (Constant_Value (Ent));
         end if;

      --  An integer literal that was either in the source or created as a
      --  result of static evaluation.

      elsif Kind = N_Integer_Literal then
         Val := Intval (N);

      --  A real literal for a fixed-point type. This must be the fixed-point
      --  case, either the literal is of a fixed-point type, or it is a bound
      --  of a fixed-point type, with type universal real. In either case we
      --  obtain the desired value from Corresponding_Integer_Value.

      elsif Kind = N_Real_Literal then
         pragma Assert (Is_Fixed_Point_Type (Underlying_Type (Etype (N))));
         Val := Corresponding_Integer_Value (N);

      --  The NULL access value

      elsif Kind = N_Null then
         pragma Assert (Is_Access_Type (Underlying_Type (Etype (N)))
           or else Error_Posted (N));
         Val := Uint_0;

      --  Character literal

      elsif Kind = N_Character_Literal then
         Ent := Entity (N);

         --  Since Character literals of type Standard.Character don't
         --  have any defining character literals built for them, they
         --  do not have their Entity set, so just use their Char
         --  code. Otherwise for user-defined character literals use
         --  their Pos value as usual.

         if No (Ent) then
            Val := Char_Literal_Value (N);
         else
            Val := Enumeration_Pos (Ent);
         end if;

      --  Unchecked conversion, which can come from System'To_Address (X)
      --  where X is a static integer expression. Recursively evaluate X.

      elsif Kind = N_Unchecked_Type_Conversion then
         Val := Expr_Value (Expression (N));

      --  Static discriminant value

      elsif Is_Static_Discriminant_Component (N) then
         Val := Expr_Value
                  (Get_Discriminant_Value
                     (Entity (Selector_Name (N)),
                      Etype (Prefix (N)),
                      Discriminant_Constraint (Etype (Prefix (N)))));

      else
         raise Program_Error;
      end if;

      --  Come here with Val set to value to be returned, set cache

      CV_Ent.N := N;
      CV_Ent.V := Val;
      return Val;
   end Expr_Value;

   ------------------
   -- Expr_Value_E --
   ------------------

   function Expr_Value_E (N : Node_Id) return Entity_Id is
      Ent : constant Entity_Id := Entity (N);
   begin
      if Ekind (Ent) = E_Enumeration_Literal then
         return Ent;
      else
         pragma Assert (Ekind (Ent) = E_Constant);

         --  We may be dealing with a enumerated character type constant, so
         --  handle that case here.

         if Nkind (Constant_Value (Ent)) = N_Character_Literal then
            return Ent;
         else
            return Expr_Value_E (Constant_Value (Ent));
         end if;
      end if;
   end Expr_Value_E;

   ------------------
   -- Expr_Value_R --
   ------------------

   function Expr_Value_R (N : Node_Id) return Ureal is
      Kind : constant Node_Kind := Nkind (N);
      Ent  : Entity_Id;

   begin
      if Kind = N_Real_Literal then
         return Realval (N);

      elsif Kind = N_Identifier or else Kind = N_Expanded_Name then
         Ent := Entity (N);
         pragma Assert (Ekind (Ent) = E_Constant);
         return Expr_Value_R (Constant_Value (Ent));

      elsif Kind = N_Integer_Literal then
         return UR_From_Uint (Expr_Value (N));

      --  Here, we have a node that cannot be interpreted as a compile time
      --  constant. That is definitely an error.

      else
         raise Program_Error;
      end if;
   end Expr_Value_R;

   ------------------
   -- Expr_Value_S --
   ------------------

   function Expr_Value_S (N : Node_Id) return Node_Id is
   begin
      if Nkind (N) = N_String_Literal then
         return N;
      else
         pragma Assert (Ekind (Entity (N)) = E_Constant);
         return Expr_Value_S (Constant_Value (Entity (N)));
      end if;
   end Expr_Value_S;

   ----------------------------------
   -- Find_Universal_Operator_Type --
   ----------------------------------

   function Find_Universal_Operator_Type (N : Node_Id) return Entity_Id is
      PN     : constant Node_Id := Parent (N);
      Call   : constant Node_Id := Original_Node (N);
      Is_Int : constant Boolean := Is_Integer_Type (Etype (N));

      Is_Fix : constant Boolean :=
                 Nkind (N) in N_Binary_Op
                   and then Nkind (Right_Opnd (N)) /= Nkind (Left_Opnd (N));
      --  A mixed-mode operation in this context indicates the presence of
      --  fixed-point type in the designated package.

      Is_Relational : constant Boolean := Etype (N) = Standard_Boolean;
      --  Case where N is a relational (or membership) operator (else it is an
      --  arithmetic one).

      In_Membership : constant Boolean :=
                        Nkind (PN) in N_Membership_Test
                          and then
                        Nkind (Right_Opnd (PN)) = N_Range
                          and then
                        Is_Universal_Numeric_Type (Etype (Left_Opnd (PN)))
                          and then
                        Is_Universal_Numeric_Type
                          (Etype (Low_Bound (Right_Opnd (PN))))
                          and then
                        Is_Universal_Numeric_Type
                          (Etype (High_Bound (Right_Opnd (PN))));
      --  Case where N is part of a membership test with a universal range

      E      : Entity_Id;
      Pack   : Entity_Id;
      Typ1   : Entity_Id := Empty;
      Priv_E : Entity_Id;

      function Is_Mixed_Mode_Operand (Op : Node_Id) return Boolean;
      --  Check whether one operand is a mixed-mode operation that requires the
      --  presence of a fixed-point type. Given that all operands are universal
      --  and have been constant-folded, retrieve the original function call.

      ---------------------------
      -- Is_Mixed_Mode_Operand --
      ---------------------------

      function Is_Mixed_Mode_Operand (Op : Node_Id) return Boolean is
         Onod : constant Node_Id := Original_Node (Op);
      begin
         return Nkind (Onod) = N_Function_Call
           and then Present (Next_Actual (First_Actual (Onod)))
           and then Etype (First_Actual (Onod)) /=
                    Etype (Next_Actual (First_Actual (Onod)));
      end Is_Mixed_Mode_Operand;

   --  Start of processing for Find_Universal_Operator_Type

   begin
      if Nkind (Call) /= N_Function_Call
        or else Nkind (Name (Call)) /= N_Expanded_Name
      then
         return Empty;

      --  There are several cases where the context does not imply the type of
      --  the operands:
      --     - the universal expression appears in a type conversion;
      --     - the expression is a relational operator applied to universal
      --       operands;
      --     - the expression is a membership test with a universal operand
      --       and a range with universal bounds.

      elsif Nkind (Parent (N)) = N_Type_Conversion
        or else Is_Relational
        or else In_Membership
      then
         Pack := Entity (Prefix (Name (Call)));

         --  If the prefix is a package declared elsewhere, iterate over its
         --  visible entities, otherwise iterate over all declarations in the
         --  designated scope.

         if Ekind (Pack) = E_Package
           and then not In_Open_Scopes (Pack)
         then
            Priv_E := First_Private_Entity (Pack);
         else
            Priv_E := Empty;
         end if;

         Typ1 := Empty;
         E := First_Entity (Pack);
         while Present (E) and then E /= Priv_E loop
            if Is_Numeric_Type (E)
              and then Nkind (Parent (E)) /= N_Subtype_Declaration
              and then Comes_From_Source (E)
              and then Is_Integer_Type (E) = Is_Int
              and then (Nkind (N) in N_Unary_Op
                         or else Is_Relational
                         or else Is_Fixed_Point_Type (E) = Is_Fix)
            then
               if No (Typ1) then
                  Typ1 := E;

               --  Before emitting an error, check for the presence of a
               --  mixed-mode operation that specifies a fixed point type.

               elsif Is_Relational
                 and then
                   (Is_Mixed_Mode_Operand (Left_Opnd (N))
                     or else Is_Mixed_Mode_Operand (Right_Opnd (N)))
                 and then Is_Fixed_Point_Type (E) /= Is_Fixed_Point_Type (Typ1)

               then
                  if Is_Fixed_Point_Type (E) then
                     Typ1 := E;
                  end if;

               else
                  --  More than one type of the proper class declared in P

                  Error_Msg_N ("ambiguous operation", N);
                  Error_Msg_Sloc := Sloc (Typ1);
                  Error_Msg_N ("\possible interpretation (inherited)#", N);
                  Error_Msg_Sloc := Sloc (E);
                  Error_Msg_N ("\possible interpretation (inherited)#", N);
                  return Empty;
               end if;
            end if;

            Next_Entity (E);
         end loop;
      end if;

      return Typ1;
   end Find_Universal_Operator_Type;

   --------------------------
   -- Flag_Non_Static_Expr --
   --------------------------

   procedure Flag_Non_Static_Expr (Msg : String; Expr : Node_Id) is
   begin
      if Error_Posted (Expr) and then not All_Errors_Mode then
         return;
      else
         Error_Msg_F (Msg, Expr);
         Why_Not_Static (Expr);
      end if;
   end Flag_Non_Static_Expr;

   ----------
   -- Fold --
   ----------

   procedure Fold (N : Node_Id) is
      Typ : constant Entity_Id := Etype (N);
   begin
      --  If not known at compile time or if already a literal, nothing to do

      if Nkind (N) in N_Numeric_Or_String_Literal
        or else not Compile_Time_Known_Value (N)
      then
         null;

      elsif Is_Discrete_Type (Typ) then
         Fold_Uint (N, Expr_Value (N), Static => Is_Static_Expression (N));

      elsif Is_Real_Type (Typ) then
         Fold_Ureal (N, Expr_Value_R (N), Static => Is_Static_Expression (N));

      elsif Is_String_Type (Typ) then
         Fold_Str
           (N, Strval (Expr_Value_S (N)), Static => Is_Static_Expression (N));
      end if;
   end Fold;

   ----------------
   -- Fold_Dummy --
   ----------------

   procedure Fold_Dummy (N : Node_Id; Typ : Entity_Id) is
   begin
      if Is_Integer_Type (Typ) then
         Fold_Uint (N, Uint_1, Static => True);

      elsif Is_Real_Type (Typ) then
         Fold_Ureal (N, Ureal_1, Static => True);

      elsif Is_Enumeration_Type (Typ) then
         Fold_Uint
           (N,
            Expr_Value (Type_Low_Bound (Base_Type (Typ))),
            Static => True);

      elsif Is_String_Type (Typ) then
         Fold_Str
           (N,
            Strval (Make_String_Literal (Sloc (N), "")),
            Static => True);
      end if;
   end Fold_Dummy;

   ----------------
   -- Fold_Shift --
   ----------------

   procedure Fold_Shift
     (N          : Node_Id;
      Left       : Node_Id;
      Right      : Node_Id;
      Op         : Node_Kind;
      Static     : Boolean := False;
      Check_Elab : Boolean := False)
   is
      Typ : constant Entity_Id := Base_Type (Etype (Left));

      procedure Check_Elab_Call;
      --  Add checks related to calls in elaboration code

      ---------------------
      -- Check_Elab_Call --
      ---------------------

      procedure Check_Elab_Call is
      begin
         if Check_Elab then
            if Legacy_Elaboration_Checks then
               Check_Elab_Call (N);
            end if;

            Build_Call_Marker (N);
         end if;
      end Check_Elab_Call;

      Modulus, Val : Uint;

   begin
      if Compile_Time_Known_Value (Left)
        and then Compile_Time_Known_Value (Right)
      then
         pragma Assert (not Non_Binary_Modulus (Typ));

         if Op = N_Op_Shift_Left then
            Check_Elab_Call;

            if Is_Modular_Integer_Type (Typ) then
               Modulus := Einfo.Entities.Modulus (Typ);
            else
               Modulus := Uint_2 ** RM_Size (Typ);
            end if;

            --  Fold Shift_Left (X, Y) by computing
            --  (X * 2**Y) rem modulus [- Modulus]

            Val := (Expr_Value (Left) * (Uint_2 ** Expr_Value (Right)))
                     rem Modulus;

            if Is_Modular_Integer_Type (Typ)
              or else Val < Modulus / Uint_2
            then
               Fold_Uint (N, Val, Static => Static);
            else
               Fold_Uint (N, Val - Modulus, Static => Static);
            end if;

         elsif Op = N_Op_Shift_Right then
            Check_Elab_Call;

            --  X >> 0 is a no-op

            if Expr_Value (Right) = Uint_0 then
               Fold_Uint (N, Expr_Value (Left), Static => Static);
            else
               if Is_Modular_Integer_Type (Typ) then
                  Modulus := Einfo.Entities.Modulus (Typ);
               else
                  Modulus := Uint_2 ** RM_Size (Typ);
               end if;

               --  Fold X >> Y by computing (X [+ Modulus]) / 2**Y
               --  Note that after a Shift_Right operation (with Y > 0), the
               --  result is always positive, even if the original operand was
               --  negative.

               declare
                  M : Unat;
               begin
                  if Expr_Value (Left) >= Uint_0 then
                     M := Uint_0;
                  else
                     M := Modulus;
                  end if;

                  Fold_Uint
                    (N,
                     (Expr_Value (Left) + M) / (Uint_2 ** Expr_Value (Right)),
                     Static => Static);
               end;
            end if;
         elsif Op = N_Op_Shift_Right_Arithmetic then
            Check_Elab_Call;

            declare
               Two_Y : constant Uint := Uint_2 ** Expr_Value (Right);
            begin
               if Is_Modular_Integer_Type (Typ) then
                  Modulus := Einfo.Entities.Modulus (Typ);
               else
                  Modulus := Uint_2 ** RM_Size (Typ);
               end if;

               --  X / 2**Y if X if positive or a small enough modular integer

               if (Is_Modular_Integer_Type (Typ)
                    and then Expr_Value (Left) < Modulus / Uint_2)
                 or else
                   (not Is_Modular_Integer_Type (Typ)
                     and then Expr_Value (Left) >= 0)
               then
                  Fold_Uint (N, Expr_Value (Left) / Two_Y, Static => Static);

               --  -1 (aka all 1's) if Y is larger than the number of bits
               --  available or if X = -1.

               elsif Two_Y > Modulus
                 or else Expr_Value (Left) = Uint_Minus_1
               then
                  if Is_Modular_Integer_Type (Typ) then
                     Fold_Uint (N, Modulus - Uint_1, Static => Static);
                  else
                     Fold_Uint (N, Uint_Minus_1, Static => Static);
                  end if;

               --  Large modular integer, compute via multiply/divide the
               --  following: X >> Y + (1 << Y - 1) << (RM_Size - Y)

               elsif Is_Modular_Integer_Type (Typ) then
                  Fold_Uint
                    (N,
                     (Expr_Value (Left)) / Two_Y
                        + (Two_Y - Uint_1)
                          * Uint_2 ** (RM_Size (Typ) - Expr_Value (Right)),
                     Static => Static);

               --  Negative signed integer, compute via multiple/divide the
               --  following:
               --  (Modulus + X) >> Y + (1 << Y - 1) << (RM_Size - Y) - Modulus

               else
                  Fold_Uint
                    (N,
                     (Modulus + Expr_Value (Left)) / Two_Y
                        + (Two_Y - Uint_1)
                          * Uint_2 ** (RM_Size (Typ) - Expr_Value (Right))
                        - Modulus,
                     Static => Static);
               end if;
            end;
         end if;
      end if;
   end Fold_Shift;

   --------------
   -- Fold_Str --
   --------------

   procedure Fold_Str (N : Node_Id; Val : String_Id; Static : Boolean) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id  := Etype (N);

   begin
      if Raises_Constraint_Error (N) then
         Set_Is_Static_Expression (N, Static);
         return;
      end if;

      Rewrite (N, Make_String_Literal (Loc, Strval => Val));

      --  We now have the literal with the right value, both the actual type
      --  and the expected type of this literal are taken from the expression
      --  that was evaluated. So now we do the Analyze and Resolve.

      --  Note that we have to reset Is_Static_Expression both after the
      --  analyze step (because Resolve will evaluate the literal, which
      --  will cause semantic errors if it is marked as static), and after
      --  the Resolve step (since Resolve in some cases resets this flag).

      Analyze (N);
      Set_Is_Static_Expression (N, Static);
      Set_Etype (N, Typ);
      Resolve (N);
      Set_Is_Static_Expression (N, Static);
   end Fold_Str;

   ---------------
   -- Fold_Uint --
   ---------------

   procedure Fold_Uint (N : Node_Id; Val : Uint; Static : Boolean) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : Entity_Id  := Etype (N);
      Ent : Entity_Id;

   begin
      if Raises_Constraint_Error (N) then
         Set_Is_Static_Expression (N, Static);
         return;
      end if;

      --  If we are folding a named number, retain the entity in the literal
      --  in the original tree.

      if Is_Entity_Name (N) and then Ekind (Entity (N)) = E_Named_Integer then
         Ent := Entity (N);
      else
         Ent := Empty;
      end if;

      if Is_Private_Type (Typ) then
         Typ := Full_View (Typ);
      end if;

      --  For a result of type integer, substitute an N_Integer_Literal node
      --  for the result of the compile time evaluation of the expression.
      --  Set a link to the original named number when not in a generic context
      --  for reference in the original tree.

      if Is_Integer_Type (Typ) then
         Rewrite (N, Make_Integer_Literal (Loc, Val));
         Set_Original_Entity (N, Ent);

      --  Otherwise we have an enumeration type, and we substitute either
      --  an N_Identifier or N_Character_Literal to represent the enumeration
      --  literal corresponding to the given value, which must always be in
      --  range, because appropriate tests have already been made for this.

      else pragma Assert (Is_Enumeration_Type (Typ));
         Rewrite (N, Get_Enum_Lit_From_Pos (Etype (N), Val, Loc));
      end if;

      --  We now have the literal with the right value, both the actual type
      --  and the expected type of this literal are taken from the expression
      --  that was evaluated. So now we do the Analyze and Resolve.

      --  Note that we have to reset Is_Static_Expression both after the
      --  analyze step (because Resolve will evaluate the literal, which
      --  will cause semantic errors if it is marked as static), and after
      --  the Resolve step (since Resolve in some cases sets this flag).

      Analyze (N);
      Set_Is_Static_Expression (N, Static);
      Set_Etype (N, Typ);
      Resolve (N);
      Set_Is_Static_Expression (N, Static);
   end Fold_Uint;

   ----------------
   -- Fold_Ureal --
   ----------------

   procedure Fold_Ureal (N : Node_Id; Val : Ureal; Static : Boolean) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id  := Etype (N);
      Ent : Entity_Id;

   begin
      if Raises_Constraint_Error (N) then
         Set_Is_Static_Expression (N, Static);
         return;
      end if;

      --  If we are folding a named number, retain the entity in the literal
      --  in the original tree.

      if Is_Entity_Name (N) and then Ekind (Entity (N)) = E_Named_Real then
         Ent := Entity (N);
      else
         Ent := Empty;
      end if;

      Rewrite (N, Make_Real_Literal (Loc, Realval => Val));

      --  Set link to original named number

      Set_Original_Entity (N, Ent);

      --  We now have the literal with the right value, both the actual type
      --  and the expected type of this literal are taken from the expression
      --  that was evaluated. So now we do the Analyze and Resolve.

      --  Note that we have to reset Is_Static_Expression both after the
      --  analyze step (because Resolve will evaluate the literal, which
      --  will cause semantic errors if it is marked as static), and after
      --  the Resolve step (since Resolve in some cases sets this flag).

      --  We mark the node as analyzed so that its type is not erased by
      --  calling Analyze_Real_Literal.

      Analyze (N);
      Set_Is_Static_Expression (N, Static);
      Set_Etype (N, Typ);
      Resolve (N);
      Set_Analyzed (N);
      Set_Is_Static_Expression (N, Static);
   end Fold_Ureal;

   ---------------
   -- From_Bits --
   ---------------

   function From_Bits (B : Bits; T : Entity_Id) return Uint is
      V : Uint := Uint_0;

   begin
      for J in 0 .. B'Last loop
         if B (J) then
            V := V + 2 ** J;
         end if;
      end loop;

      if Non_Binary_Modulus (T) then
         V := V mod Modulus (T);
      end if;

      return V;
   end From_Bits;

   --------------------
   -- Get_String_Val --
   --------------------

   function Get_String_Val (N : Node_Id) return Node_Id is
   begin
      if Nkind (N) in N_String_Literal | N_Character_Literal then
         return N;
      else
         pragma Assert (Is_Entity_Name (N));
         return Get_String_Val (Constant_Value (Entity (N)));
      end if;
   end Get_String_Val;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
   begin
      CV_Cache := (others => (Node_High_Bound, Uint_0));
   end Initialize;

   --------------------
   -- In_Subrange_Of --
   --------------------

   function In_Subrange_Of
     (T1        : Entity_Id;
      T2        : Entity_Id;
      Fixed_Int : Boolean := False) return Boolean
   is
      L1 : Node_Id;
      H1 : Node_Id;

      L2 : Node_Id;
      H2 : Node_Id;

   begin
      if T1 = T2 or else Is_Subtype_Of (T1, T2) then
         return True;

      --  Never in range if both types are not scalar. Don't know if this can
      --  actually happen, but just in case.

      elsif not Is_Scalar_Type (T1) or else not Is_Scalar_Type (T2) then
         return False;

      --  If T1 has infinities but T2 doesn't have infinities, then T1 is
      --  definitely not compatible with T2.

      elsif Is_Floating_Point_Type (T1)
        and then Has_Infinities (T1)
        and then Is_Floating_Point_Type (T2)
        and then not Has_Infinities (T2)
      then
         return False;

      else
         L1 := Type_Low_Bound  (T1);
         H1 := Type_High_Bound (T1);

         L2 := Type_Low_Bound  (T2);
         H2 := Type_High_Bound (T2);

         --  Check bounds to see if comparison possible at compile time

         if Compile_Time_Compare (L1, L2, Assume_Valid => True) in Compare_GE
              and then
            Compile_Time_Compare (H1, H2, Assume_Valid => True) in Compare_LE
         then
            return True;
         end if;

         --  If bounds not comparable at compile time, then the bounds of T2
         --  must be compile-time-known or we cannot answer the query.

         if not Compile_Time_Known_Value (L2)
           or else not Compile_Time_Known_Value (H2)
         then
            return False;
         end if;

         --  If the bounds of T1 are know at compile time then use these
         --  ones, otherwise use the bounds of the base type (which are of
         --  course always static).

         if not Compile_Time_Known_Value (L1) then
            L1 := Type_Low_Bound (Base_Type (T1));
         end if;

         if not Compile_Time_Known_Value (H1) then
            H1 := Type_High_Bound (Base_Type (T1));
         end if;

         --  Fixed point types should be considered as such only if
         --  flag Fixed_Int is set to False.

         if Is_Floating_Point_Type (T1) or else Is_Floating_Point_Type (T2)
           or else (Is_Fixed_Point_Type (T1) and then not Fixed_Int)
           or else (Is_Fixed_Point_Type (T2) and then not Fixed_Int)
         then
            return
              Expr_Value_R (L2) <= Expr_Value_R (L1)
                and then
              Expr_Value_R (H2) >= Expr_Value_R (H1);

         else
            return
              Expr_Value (L2) <= Expr_Value (L1)
                and then
              Expr_Value (H2) >= Expr_Value (H1);

         end if;
      end if;

   --  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 the answer in this case after all.

   exception
      when others =>
         --  With debug flag K we will get an exception unless an error has
         --  already occurred (useful for debugging).

         if Debug_Flag_K then
            Check_Error_Detected;
         end if;

         return False;
   end In_Subrange_Of;

   -----------------
   -- Is_In_Range --
   -----------------

   function Is_In_Range
     (N            : Node_Id;
      Typ          : Entity_Id;
      Assume_Valid : Boolean := False;
      Fixed_Int    : Boolean := False;
      Int_Real     : Boolean := False) return Boolean
   is
   begin
      return
        Test_In_Range (N, Typ, Assume_Valid, Fixed_Int, Int_Real) = In_Range;
   end Is_In_Range;

   -------------------
   -- Is_Null_Range --
   -------------------

   function Is_Null_Range (Lo : Node_Id; Hi : Node_Id) return Boolean is
   begin
      if Compile_Time_Known_Value (Lo)
        and then Compile_Time_Known_Value (Hi)
      then
         declare
            Typ : Entity_Id := Etype (Lo);
         begin
            --  When called from the frontend, as part of the analysis of
            --  potentially static expressions, Typ will be the full view of a
            --  type with all the info needed to answer this query. When called
            --  from the backend, for example to know whether a range of a loop
            --  is null, Typ might be a private type and we need to explicitly
            --  switch to its corresponding full view to access the same info.

            if Is_Incomplete_Or_Private_Type (Typ)
              and then Present (Full_View (Typ))
            then
               Typ := Full_View (Typ);
            end if;

            if Is_Discrete_Type (Typ) then
               return Expr_Value (Lo) > Expr_Value (Hi);
            else pragma Assert (Is_Real_Type (Typ));
               return Expr_Value_R (Lo) > Expr_Value_R (Hi);
            end if;
         end;

      else
         return Compile_Time_Compare (Lo, Hi, Assume_Valid => False) = GT;
      end if;
   end Is_Null_Range;

   -------------------------
   -- Is_OK_Static_Choice --
   -------------------------

   function Is_OK_Static_Choice (Choice : Node_Id) return Boolean is
   begin
      --  Check various possibilities for choice

      --  Note: for membership tests, we test more cases than are possible
      --  (in particular subtype indication), but it doesn't matter because
      --  it just won't occur (we have already done a syntax check).

      if Nkind (Choice) = N_Others_Choice then
         return True;

      elsif Nkind (Choice) = N_Range then
         return Is_OK_Static_Range (Choice);

      elsif Nkind (Choice) = N_Subtype_Indication
        or else (Is_Entity_Name (Choice) and then Is_Type (Entity (Choice)))
      then
         return Is_OK_Static_Subtype (Etype (Choice));

      else
         return Is_OK_Static_Expression (Choice);
      end if;
   end Is_OK_Static_Choice;

   ------------------------------
   -- Is_OK_Static_Choice_List --
   ------------------------------

   function Is_OK_Static_Choice_List (Choices : List_Id) return Boolean is
      Choice : Node_Id;

   begin
      if not Is_Static_Choice_List (Choices) then
         return False;
      end if;

      Choice := First (Choices);
      while Present (Choice) loop
         if not Is_OK_Static_Choice (Choice) then
            Set_Raises_Constraint_Error (Choice);
            return False;
         end if;

         Next (Choice);
      end loop;

      return True;
   end Is_OK_Static_Choice_List;

   -----------------------------
   -- Is_OK_Static_Expression --
   -----------------------------

   function Is_OK_Static_Expression (N : Node_Id) return Boolean is
   begin
      return Is_Static_Expression (N) and then not Raises_Constraint_Error (N);
   end Is_OK_Static_Expression;

   ------------------------
   -- Is_OK_Static_Range --
   ------------------------

   --  A static range is a range whose bounds are static expressions, or a
   --  Range_Attribute_Reference equivalent to such a range (RM 4.9(26)).
   --  We have already converted range attribute references, so we get the
   --  "or" part of this rule without needing a special test.

   function Is_OK_Static_Range (N : Node_Id) return Boolean is
   begin
      return Is_OK_Static_Expression (Low_Bound (N))
        and then Is_OK_Static_Expression (High_Bound (N));
   end Is_OK_Static_Range;

   --------------------------
   -- Is_OK_Static_Subtype --
   --------------------------

   --  Determines if Typ is a static subtype as defined in (RM 4.9(26)) where
   --  neither bound raises Constraint_Error when evaluated.

   function Is_OK_Static_Subtype (Typ : Entity_Id) return Boolean is
      Base_T   : constant Entity_Id := Base_Type (Typ);
      Anc_Subt : Entity_Id;

   begin
      --  First a quick check on the non static subtype flag. As described
      --  in further detail in Einfo, this flag is not decisive in all cases,
      --  but if it is set, then the subtype is definitely non-static.

      if Is_Non_Static_Subtype (Typ) then
         return False;
      end if;

      --  Then, check if the subtype is strictly static. This takes care of
      --  checking for generics and predicates.

      if not Is_Static_Subtype (Typ) then
         return False;
      end if;

      --  String types

      if Is_String_Type (Typ) then
         return
           Ekind (Typ) = E_String_Literal_Subtype
             or else
               (Is_OK_Static_Subtype (Component_Type (Typ))
                 and then Is_OK_Static_Subtype (Etype (First_Index (Typ))));

      --  Scalar types

      elsif Is_Scalar_Type (Typ) then
         if Base_T = Typ then
            return True;

         else
            Anc_Subt := Ancestor_Subtype (Typ);

            if No (Anc_Subt) then
               Anc_Subt := Base_T;
            end if;

            --  Scalar_Range (Typ) might be an N_Subtype_Indication, so use
            --  Get_Type_{Low,High}_Bound.

            return     Is_OK_Static_Subtype (Anc_Subt)
              and then Is_OK_Static_Expression (Type_Low_Bound (Typ))
              and then Is_OK_Static_Expression (Type_High_Bound (Typ));
         end if;

      --  Types other than string and scalar types are never static

      else
         return False;
      end if;
   end Is_OK_Static_Subtype;

   ---------------------
   -- Is_Out_Of_Range --
   ---------------------

   function Is_Out_Of_Range
     (N            : Node_Id;
      Typ          : Entity_Id;
      Assume_Valid : Boolean := False;
      Fixed_Int    : Boolean := False;
      Int_Real     : Boolean := False) return Boolean
   is
   begin
      return Test_In_Range (N, Typ, Assume_Valid, Fixed_Int, Int_Real) =
                                                               Out_Of_Range;
   end Is_Out_Of_Range;

   ----------------------
   -- Is_Static_Choice --
   ----------------------

   function Is_Static_Choice (Choice : Node_Id) return Boolean is
   begin
      --  Check various possibilities for choice

      --  Note: for membership tests, we test more cases than are possible
      --  (in particular subtype indication), but it doesn't matter because
      --  it just won't occur (we have already done a syntax check).

      if Nkind (Choice) = N_Others_Choice then
         return True;

      elsif Nkind (Choice) = N_Range then
         return Is_Static_Range (Choice);

      elsif Nkind (Choice) = N_Subtype_Indication
        or else (Is_Entity_Name (Choice) and then Is_Type (Entity (Choice)))
      then
         return Is_Static_Subtype (Etype (Choice));

      else
         return Is_Static_Expression (Choice);
      end if;
   end Is_Static_Choice;

   ---------------------------
   -- Is_Static_Choice_List --
   ---------------------------

   function Is_Static_Choice_List (Choices : List_Id) return Boolean is
      Choice : Node_Id;

   begin
      Choice := First (Choices);
      while Present (Choice) loop
         if not Is_Static_Choice (Choice) then
            return False;
         end if;

         Next (Choice);
      end loop;

      return True;
   end Is_Static_Choice_List;

   ---------------------
   -- Is_Static_Range --
   ---------------------

   --  A static range is a range whose bounds are static expressions, or a
   --  Range_Attribute_Reference equivalent to such a range (RM 4.9(26)).
   --  We have already converted range attribute references, so we get the
   --  "or" part of this rule without needing a special test.

   function Is_Static_Range (N : Node_Id) return Boolean is
   begin
      return Is_Static_Expression (Low_Bound  (N))
               and then
             Is_Static_Expression (High_Bound (N));
   end Is_Static_Range;

   -----------------------
   -- Is_Static_Subtype --
   -----------------------

   --  Determines if Typ is a static subtype as defined in (RM 4.9(26))

   function Is_Static_Subtype (Typ : Entity_Id) return Boolean is
      Base_T   : constant Entity_Id := Base_Type (Typ);
      Anc_Subt : Entity_Id;

   begin
      --  First a quick check on the non static subtype flag. As described
      --  in further detail in Einfo, this flag is not decisive in all cases,
      --  but if it is set, then the subtype is definitely non-static.

      if Is_Non_Static_Subtype (Typ) then
         return False;
      end if;

      Anc_Subt := Ancestor_Subtype (Typ);

      if Anc_Subt = Empty then
         Anc_Subt := Base_T;
      end if;

      if Is_Generic_Type (Root_Type (Base_T))
        or else Is_Generic_Actual_Type (Base_T)
      then
         return False;

      --  If there is a non-static predicate for the type (declared or
      --  inherited) the expression is not static.

      elsif Has_Dynamic_Predicate_Aspect (Typ)
        or else (Is_Derived_Type (Typ)
                  and then Has_Aspect (Typ, Aspect_Dynamic_Predicate))
        or else Has_Ghost_Predicate_Aspect (Typ)
        or else (Is_Derived_Type (Typ)
                 and then Has_Aspect (Typ, Aspect_Ghost_Predicate))
        or else (Has_Aspect (Typ, Aspect_Predicate)
                  and then not Has_Static_Predicate (Typ))
      then
         return False;

      --  String types

      elsif Is_String_Type (Typ) then
         return
           Ekind (Typ) = E_String_Literal_Subtype
             or else (Is_Static_Subtype (Component_Type (Typ))
                       and then Is_Static_Subtype (Etype (First_Index (Typ))));

      --  Scalar types

      elsif Is_Scalar_Type (Typ) then
         if Base_T = Typ then
            return True;

         else
            return     Is_Static_Subtype (Anc_Subt)
              and then Is_Static_Expression (Type_Low_Bound (Typ))
              and then Is_Static_Expression (Type_High_Bound (Typ));
         end if;

      --  Types other than string and scalar types are never static

      else
         return False;
      end if;
   end Is_Static_Subtype;

   -------------------------------
   -- Is_Statically_Unevaluated --
   -------------------------------

   function Is_Statically_Unevaluated (Expr : Node_Id) return Boolean is
      function Check_Case_Expr_Alternative
        (CEA : Node_Id) return Match_Result;
      --  We have a message emanating from the Expression of a case expression
      --  alternative. We examine this alternative, as follows:
      --
      --  If the selecting expression of the parent case is non-static, or
      --  if any of the discrete choices of the given case alternative are
      --  non-static or raise Constraint_Error, return Non_Static.
      --
      --  Otherwise check if the selecting expression matches any of the given
      --  discrete choices. If so, the alternative is executed and we return
      --  Match, otherwise, the alternative can never be executed, and so we
      --  return No_Match.

      ---------------------------------
      -- Check_Case_Expr_Alternative --
      ---------------------------------

      function Check_Case_Expr_Alternative
        (CEA : Node_Id) return Match_Result
      is
         Case_Exp : constant Node_Id := Parent (CEA);
         Choice   : Node_Id;
         Prev_CEA : Node_Id;

      begin
         pragma Assert (Nkind (Case_Exp) = N_Case_Expression);

         --  Check that selecting expression is static

         if not Is_OK_Static_Expression (Expression (Case_Exp)) then
            return Non_Static;
         end if;

         if not Is_OK_Static_Choice_List (Discrete_Choices (CEA)) then
            return Non_Static;
         end if;

         --  All choices are now known to be static. Now see if alternative
         --  matches one of the choices.

         Choice := First (Discrete_Choices (CEA));
         while Present (Choice) loop

            --  Check various possibilities for choice, returning Match if we
            --  find the selecting value matches any of the choices. Note that
            --  we know we are the last choice, so we don't have to keep going.

            if Nkind (Choice) = N_Others_Choice then

               --  Others choice is a bit annoying, it matches if none of the
               --  previous alternatives matches (note that we know we are the
               --  last alternative in this case, so we can just go backwards
               --  from us to see if any previous one matches).

               Prev_CEA := Prev (CEA);
               while Present (Prev_CEA) loop
                  if Check_Case_Expr_Alternative (Prev_CEA) = Match then
                     return No_Match;
                  end if;

                  Prev (Prev_CEA);
               end loop;

               return Match;

            --  Else we have a normal static choice

            elsif Choice_Matches (Expression (Case_Exp), Choice) = Match then
               return Match;
            end if;

            --  If we fall through, it means that the discrete choice did not
            --  match the selecting expression, so continue.

            Next (Choice);
         end loop;

         --  If we get through that loop then all choices were static, and none
         --  of them matched the selecting expression. So return No_Match.

         return No_Match;
      end Check_Case_Expr_Alternative;

      --  Local variables

      P      : Node_Id;
      OldP   : Node_Id;
      Choice : Node_Id;

   --  Start of processing for Is_Statically_Unevaluated

   begin
      --  The (32.x) references here are from RM section 4.9

      --  (32.1) An expression is statically unevaluated if it is part of ...

      --  This means we have to climb the tree looking for one of the cases

      P := Expr;
      loop
         OldP := P;
         P := Parent (P);

         --  (32.2) The right operand of a static short-circuit control form
         --  whose value is determined by its left operand.

         --  AND THEN with False as left operand

         if Nkind (P) = N_And_Then
           and then Compile_Time_Known_Value (Left_Opnd (P))
           and then Is_False (Expr_Value (Left_Opnd (P)))
         then
            return True;

         --  OR ELSE with True as left operand

         elsif Nkind (P) = N_Or_Else
           and then Compile_Time_Known_Value (Left_Opnd (P))
           and then Is_True (Expr_Value (Left_Opnd (P)))
         then
            return True;

         --  (32.3) A dependent_expression of an if_expression whose associated
         --  condition is static and equals False.

         elsif Nkind (P) = N_If_Expression then
            declare
               Cond : constant Node_Id := First (Expressions (P));
               Texp : constant Node_Id := Next (Cond);
               Fexp : constant Node_Id := Next (Texp);

            begin
               if Compile_Time_Known_Value (Cond) then

                  --  Condition is True and we are in the right operand

                  if Is_True (Expr_Value (Cond)) and then OldP = Fexp then
                     return True;

                  --  Condition is False and we are in the left operand

                  elsif Is_False (Expr_Value (Cond)) and then OldP = Texp then
                     return True;
                  end if;
               end if;
            end;

         --  (32.4) A condition or dependent_expression of an if_expression
         --  where the condition corresponding to at least one preceding
         --  dependent_expression of the if_expression is static and equals
         --  True.

         --  This refers to cases like

         --    (if True then 1 elsif 1/0=2 then 2 else 3)

         --  But we expand elsif's out anyway, so the above looks like:

         --    (if True then 1 else (if 1/0=2 then 2 else 3))

         --  So for us this is caught by the above check for the 32.3 case.

         --  (32.5) A dependent_expression of a case_expression whose
         --  selecting_expression is static and whose value is not covered
         --  by the corresponding discrete_choice_list.

         elsif Nkind (P) = N_Case_Expression_Alternative then

            --  First, we have to be in the expression to suppress messages.
            --  If we are within one of the choices, we want the message.

            if OldP = Expression (P) then

               --  Statically unevaluated if alternative does not match

               if Check_Case_Expr_Alternative (P) = No_Match then
                  return True;
               end if;
            end if;

         --  (32.6) A choice_expression (or a simple_expression of a range
         --  that occurs as a membership_choice of a membership_choice_list)
         --  of a static membership test that is preceded in the enclosing
         --  membership_choice_list by another item whose individual
         --  membership test (see (RM 4.5.2)) statically yields True.

         elsif Nkind (P) in N_Membership_Test then

            --  Only possibly unevaluated if simple expression is static

            if not Is_OK_Static_Expression (Left_Opnd (P)) then
               null;

            --  All members of the choice list must be static

            elsif (Present (Right_Opnd (P))
                    and then not Is_OK_Static_Choice (Right_Opnd (P)))
              or else (Present (Alternatives (P))
                        and then
                          not Is_OK_Static_Choice_List (Alternatives (P)))
            then
               null;

            --  If expression is the one and only alternative, then it is
            --  definitely not statically unevaluated, so we only have to
            --  test the case where there are alternatives present.

            elsif Present (Alternatives (P)) then

               --  Look for previous matching Choice

               Choice := First (Alternatives (P));
               while Present (Choice) loop

                  --  If we reached us and no previous choices matched, this
                  --  is not the case where we are statically unevaluated.

                  exit when OldP = Choice;

                  --  If a previous choice matches, then that is the case where
                  --  we know our choice is statically unevaluated.

                  if Choice_Matches (Left_Opnd (P), Choice) = Match then
                     return True;
                  end if;

                  Next (Choice);
               end loop;

               --  If we fall through the loop, we were not one of the choices,
               --  we must have been the expression, so that is not covered by
               --  this rule, and we keep going.

               null;
            end if;
         end if;

         --  OK, not statically unevaluated at this level, see if we should
         --  keep climbing to look for a higher level reason.

         --  Special case for component association in aggregates, where
         --  we want to keep climbing up to the parent aggregate.

         if Nkind (P) = N_Component_Association
           and then Nkind (Parent (P)) = N_Aggregate
         then
            null;

         --  All done if not still within subexpression

         else
            exit when Nkind (P) not in N_Subexpr;
         end if;
      end loop;

      --  If we fall through the loop, not one of the cases covered!

      return False;
   end Is_Statically_Unevaluated;

   --------------------
   -- Machine_Number --
   --------------------

   --  Historical note: RM 4.9(38) originally specified biased rounding but
   --  this has been modified by AI-268 to prevent confusing differences in
   --  rounding between static and nonstatic expressions. This AI specifies
   --  that the effect of such rounding is implementation-dependent instead,
   --  and in GNAT we round to nearest even to match the run-time behavior.
   --  Note that this applies to floating-point literals, not fixed-point
   --  ones, even though their representation is also a universal real.

   function Machine_Number
     (Typ : Entity_Id;
      Val : Ureal;
      N   : Node_Id) return Ureal
   is
   begin
      return Machine (Typ, Val, Round_Even, N);
   end Machine_Number;

   --------------------
   -- Not_Null_Range --
   --------------------

   function Not_Null_Range (Lo : Node_Id; Hi : Node_Id) return Boolean is
   begin
      if Compile_Time_Known_Value (Lo)
        and then Compile_Time_Known_Value (Hi)
      then
         declare
            Typ : Entity_Id := Etype (Lo);
         begin
            --  When called from the frontend, as part of the analysis of
            --  potentially static expressions, Typ will be the full view of a
            --  type with all the info needed to answer this query. When called
            --  from the backend, for example to know whether a range of a loop
            --  is null, Typ might be a private type and we need to explicitly
            --  switch to its corresponding full view to access the same info.

            if Is_Incomplete_Or_Private_Type (Typ)
              and then Present (Full_View (Typ))
            then
               Typ := Full_View (Typ);
            end if;

            if Is_Discrete_Type (Typ) then
               return Expr_Value (Lo) <= Expr_Value (Hi);
            else pragma Assert (Is_Real_Type (Typ));
               return Expr_Value_R (Lo) <= Expr_Value_R (Hi);
            end if;
         end;

      else
         return
           Compile_Time_Compare (Lo, Hi, Assume_Valid => False) in Compare_LE;
      end if;
   end Not_Null_Range;

   -------------
   -- OK_Bits --
   -------------

   function OK_Bits (N : Node_Id; Bits : Uint) return Boolean is
   begin
      --  We allow a maximum of 500,000 bits which seems a reasonable limit

      if Bits < 500_000 then
         return True;

      --  Error if this maximum is exceeded

      else
         Error_Msg_N ("static value too large, capacity exceeded", N);
         return False;
      end if;
   end OK_Bits;

   ------------------
   -- Out_Of_Range --
   ------------------

   procedure Out_Of_Range (N : Node_Id) is

      --  If the FE conjures up an expression that would normally be
      --  an illegal static expression (e.g., an integer literal with
      --  a value outside of its base subtype), we don't want to
      --  flag it as illegal; we only want a warning in such cases.

      function Force_Warning return Boolean is
        (if Comes_From_Source (Original_Node (N)) then False
         elsif Nkind (Original_Node (N)) = N_Type_Conversion then True
         else Is_Null_Array_Aggregate_High_Bound (N));
   begin
      --  If we have the static expression case, then this is an illegality
      --  in Ada 95 mode, except that in an instance, we never generate an
      --  error (if the error is legitimate, it was already diagnosed in the
      --  template).

      if Is_Static_Expression (N)
        and then not In_Instance
        and then not In_Inlined_Body
        and then Ada_Version >= Ada_95
      then
         --  No message if we are statically unevaluated

         if Is_Statically_Unevaluated (N) then
            null;

         --  The expression to compute the length of a packed array is attached
         --  to the array type itself, and deserves a separate message.

         elsif Nkind (Parent (N)) = N_Defining_Identifier
           and then Is_Array_Type (Parent (N))
           and then Present (Packed_Array_Impl_Type (Parent (N)))
           and then Present (First_Rep_Item (Parent (N)))
         then
            Error_Msg_N
             ("length of packed array must not exceed Integer''Last",
              First_Rep_Item (Parent (N)));
            Rewrite (N, Make_Integer_Literal (Sloc (N), Uint_1));

         --  All cases except the special array case.
         --  No message if we are dealing with System.Priority values in
         --  CodePeer mode where the target runtime may have more priorities.

         elsif not CodePeer_Mode
           or else not Is_RTE (Etype (N), RE_Priority)
         then
            --  Determine if the out-of-range violation constitutes a warning
            --  or an error based on context, according to RM 4.9 (34/3).

            if Force_Warning then
               Apply_Compile_Time_Constraint_Error
                 (N, "value not in range of}??", CE_Range_Check_Failed);
            else
               Apply_Compile_Time_Constraint_Error
                 (N, "value not in range of}", CE_Range_Check_Failed);
            end if;
         end if;

      --  Here we generate a warning for the Ada 83 case, or when we are in an
      --  instance, or when we have a non-static expression case.

      else
         Apply_Compile_Time_Constraint_Error
           (N, "value not in range of}??", CE_Range_Check_Failed);
      end if;
   end Out_Of_Range;

   ---------------------------
   -- Predicates_Compatible --
   ---------------------------

   function Predicates_Compatible (T1, T2 : Entity_Id) return Boolean is

      function T2_Rep_Item_Applies_To_T1 (Nam : Name_Id) return Boolean;
      --  Return True if the rep item for Nam is either absent on T2 or also
      --  applies to T1.

      -------------------------------
      -- T2_Rep_Item_Applies_To_T1 --
      -------------------------------

      function T2_Rep_Item_Applies_To_T1 (Nam : Name_Id) return Boolean is
         Rep_Item : constant Node_Id := Get_Rep_Item (T2, Nam);

      begin
         return No (Rep_Item) or else Get_Rep_Item (T1, Nam) = Rep_Item;
      end T2_Rep_Item_Applies_To_T1;

   --  Start of processing for Predicates_Compatible

   begin
      if Ada_Version < Ada_2012 then
         return True;

      --  If T2 has no predicates, there is no compatibility issue

      elsif not Has_Predicates (T2) then
         return True;

      --  T2 has predicates, if T1 has none then we defer to the static check

      elsif not Has_Predicates (T1) then
         null;

      --  Both T2 and T1 have predicates, check that all predicates that apply
      --  to T2 apply also to T1 (RM 4.9.1(9/3)).

      elsif T2_Rep_Item_Applies_To_T1 (Name_Static_Predicate)
        and then T2_Rep_Item_Applies_To_T1 (Name_Dynamic_Predicate)
        and then T2_Rep_Item_Applies_To_T1 (Name_Predicate)
      then
         return True;
      end if;

      --  Implement the static check prescribed by RM 4.9.1(10/3)

      if Is_Static_Subtype (T1) and then Is_Static_Subtype (T2) then
         --  We just need to query Interval_Lists for discrete types

         if Is_Discrete_Type (T1) and then Is_Discrete_Type (T2) then
            declare
               Interval_List1 : constant Interval_Lists.Discrete_Interval_List
                 := Interval_Lists.Type_Intervals (T1);
               Interval_List2 : constant Interval_Lists.Discrete_Interval_List
                 := Interval_Lists.Type_Intervals (T2);
            begin
               return Interval_Lists.Is_Subset (Interval_List1, Interval_List2)
                 and then not (Has_Predicates (T1)
                                and then not Predicate_Checks_Suppressed (T2)
                                and then Predicate_Checks_Suppressed (T1));
            end;

         else
            --  ??? Need to implement Interval_Lists for real types

            return False;
         end if;

      --  If either subtype is not static, the predicates are not compatible

      else
         return False;
      end if;
   end Predicates_Compatible;

   ----------------------
   -- Predicates_Match --
   ----------------------

   function Predicates_Match (T1, T2 : Entity_Id) return Boolean is

      function Have_Same_Rep_Item (Nam : Name_Id) return Boolean;
      --  Return True if T1 and T2 have the same rep item for Nam

      ------------------------
      -- Have_Same_Rep_Item --
      ------------------------

      function Have_Same_Rep_Item (Nam : Name_Id) return Boolean is
      begin
         return Get_Rep_Item (T1, Nam) = Get_Rep_Item (T2, Nam);
      end Have_Same_Rep_Item;

   --  Start of processing for Predicates_Match

   begin
      if Ada_Version < Ada_2012 then
         return True;

      --  If T2 has no predicates, match if and only if T1 has none

      elsif not Has_Predicates (T2) then
         return not Has_Predicates (T1);

      --  T2 has predicates, no match if T1 has none

      elsif not Has_Predicates (T1) then
         return False;

      --  Both T2 and T1 have predicates, check that they all come
      --  from the same declarations.

      else
         return Have_Same_Rep_Item (Name_Static_Predicate)
           and then Have_Same_Rep_Item (Name_Dynamic_Predicate)
           and then Have_Same_Rep_Item (Name_Predicate);
      end if;
   end Predicates_Match;

   ---------------------------------------------
   -- Real_Or_String_Static_Predicate_Matches --
   ---------------------------------------------

   function Real_Or_String_Static_Predicate_Matches
     (Val : Node_Id;
      Typ : Entity_Id) return Boolean
   is
      Expr : constant Node_Id := Static_Real_Or_String_Predicate (Typ);
      --  The predicate expression from the type

      Pfun : constant Entity_Id := Predicate_Function (Typ);
      --  The entity for the predicate function

      Ent_Name : constant Name_Id := Chars (First_Formal (Pfun));
      --  The name of the formal of the predicate function. Occurrences of the
      --  type name in Expr have been rewritten as references to this formal,
      --  and it has a unique name, so we can identify references by this name.

      Copy : Node_Id;
      --  Copy of the predicate function tree

      function Process (N : Node_Id) return Traverse_Result;
      --  Function used to process nodes during the traversal in which we will
      --  find occurrences of the entity name, and replace such occurrences
      --  by a real literal with the value to be tested.

      procedure Traverse is new Traverse_Proc (Process);
      --  The actual traversal procedure

      -------------
      -- Process --
      -------------

      function Process (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) = N_Identifier and then Chars (N) = Ent_Name then
            declare
               Nod : constant Node_Id := New_Copy (Val);
            begin
               Set_Sloc (Nod, Sloc (N));
               Rewrite (N, Nod);
               return Skip;
            end;

         --  The predicate function may contain string-comparison operations
         --  that have been converted into calls to run-time array-comparison
         --  routines. To evaluate the predicate statically, we recover the
         --  original comparison operation and replace the occurrence of the
         --  formal by the static string value. The actuals of the generated
         --  call are of the form X'Address.

         elsif Nkind (N) in N_Op_Compare
           and then Nkind (Left_Opnd (N)) = N_Function_Call
         then
            declare
               C : constant Node_Id := Left_Opnd (N);
               F : constant Node_Id := First (Parameter_Associations (C));
               L : constant Node_Id := Prefix (F);
               R : constant Node_Id := Prefix (Next (F));

            begin
               --  If an operand is an entity name, it is the formal of the
               --  predicate function, so replace it with the string value.
               --  It may be either operand in the call. The other operand
               --  is a static string from the original predicate.

               if Is_Entity_Name (L) then
                  Rewrite (Left_Opnd (N),  New_Copy (Val));
                  Rewrite (Right_Opnd (N), New_Copy (R));

               else
                  Rewrite (Left_Opnd (N),  New_Copy (L));
                  Rewrite (Right_Opnd (N), New_Copy (Val));
               end if;

               return Skip;
            end;

         else
            return OK;
         end if;
      end Process;

   --  Start of processing for Real_Or_String_Static_Predicate_Matches

   begin
      --  First deal with special case of inherited predicate, where the
      --  predicate expression looks like:

      --     xxPredicate (typ (Ent)) and then Expr

      --  where Expr is the predicate expression for this level, and the
      --  left operand is the call to evaluate the inherited predicate.

      if Nkind (Expr) = N_And_Then
        and then Nkind (Left_Opnd (Expr)) = N_Function_Call
        and then Is_Predicate_Function (Entity (Name (Left_Opnd (Expr))))
      then
         --  OK we have the inherited case, so make a call to evaluate the
         --  inherited predicate. If that fails, so do we!

         if not
           Real_Or_String_Static_Predicate_Matches
             (Val => Val,
              Typ => Etype (First_Formal (Entity (Name (Left_Opnd (Expr))))))
         then
            return False;
         end if;

         --  Use the right operand for the continued processing

         Copy := Copy_Separate_Tree (Right_Opnd (Expr));

      --  Case where call to predicate function appears on its own (this means
      --  that the predicate at this level is just inherited from the parent).

      elsif Nkind (Expr) = N_Function_Call then
         declare
            Typ : constant Entity_Id :=
                    Etype (First_Formal (Entity (Name (Expr))));

         begin
            --  If the inherited predicate is not static, just ignore it. We
            --  can't go trying to evaluate a dynamic predicate as a static
            --  one!

            if Has_Dynamic_Predicate_Aspect (Typ)
              or else Has_Ghost_Predicate_Aspect (Typ)
            then
               return True;

            --  Otherwise inherited predicate is static, check for match

            else
               return Real_Or_String_Static_Predicate_Matches (Val, Typ);
            end if;
         end;

      --  If not just an inherited predicate, copy whole expression

      else
         Copy := Copy_Separate_Tree (Expr);
      end if;

      --  Now we replace occurrences of the entity by the value

      Traverse (Copy);

      --  And analyze the resulting static expression to see if it is True

      Analyze_And_Resolve (Copy, Standard_Boolean);
      return Is_True (Expr_Value (Copy));
   end Real_Or_String_Static_Predicate_Matches;

   -------------------------
   -- Rewrite_In_Raise_CE --
   -------------------------

   procedure Rewrite_In_Raise_CE (N : Node_Id; Exp : Node_Id) is
      Stat : constant Boolean   := Is_Static_Expression (N);
      Typ  : constant Entity_Id := Etype (N);

   begin
      --  If we want to raise CE in the condition of a N_Raise_CE node, we
      --  can just clear the condition if the reason is appropriate. We do
      --  not do this operation if the parent has a reason other than range
      --  check failed, because otherwise we would change the reason.

      if Present (Parent (N))
        and then Nkind (Parent (N)) = N_Raise_Constraint_Error
        and then Reason (Parent (N)) =
                   UI_From_Int (RT_Exception_Code'Pos (CE_Range_Check_Failed))
      then
         Set_Condition (Parent (N), Empty);

      --  Else build an explicit N_Raise_CE

      else
         if Nkind (Exp) = N_Raise_Constraint_Error then
            Rewrite (N,
              Make_Raise_Constraint_Error (Sloc (Exp),
                Reason => Reason (Exp)));
         else
            Rewrite (N,
              Make_Raise_Constraint_Error (Sloc (Exp),
                Reason => CE_Range_Check_Failed));
         end if;

         Set_Raises_Constraint_Error (N);
         Set_Etype (N, Typ);
      end if;

      --  Set proper flags in result

      Set_Raises_Constraint_Error (N, True);
      Set_Is_Static_Expression (N, Stat);
   end Rewrite_In_Raise_CE;

   ------------------------------------------------
   -- Set_Checking_Potentially_Static_Expression --
   ------------------------------------------------

   procedure Set_Checking_Potentially_Static_Expression (Value : Boolean) is
   begin
      --  Verify that we only start/stop checking for a potentially static
      --  expression and do not start or stop it twice in a row.

      pragma Assert (Checking_For_Potentially_Static_Expression /= Value);

      Checking_For_Potentially_Static_Expression := Value;
   end Set_Checking_Potentially_Static_Expression;

   ---------------------
   -- String_Type_Len --
   ---------------------

   function String_Type_Len (Stype : Entity_Id) return Uint is
      NT : constant Entity_Id := Etype (First_Index (Stype));
      T  : Entity_Id;

   begin
      if Is_OK_Static_Subtype (NT) then
         T := NT;
      else
         T := Base_Type (NT);
      end if;

      return Expr_Value (Type_High_Bound (T)) -
             Expr_Value (Type_Low_Bound (T)) + 1;
   end String_Type_Len;

   ------------------------------------
   -- Subtypes_Statically_Compatible --
   ------------------------------------

   function Subtypes_Statically_Compatible
     (T1                      : Entity_Id;
      T2                      : Entity_Id;
      Formal_Derived_Matching : Boolean := False) return Boolean
   is
   begin
      --  A type is always statically compatible with itself

      if T1 = T2 then
         return True;

      --  Not compatible if predicates are not compatible

      elsif not Predicates_Compatible (T1, T2) then
         return False;

      --  Scalar types

      elsif Is_Scalar_Type (T1) then

         --  Definitely compatible if we match

         if Subtypes_Statically_Match (T1, T2) then
            return True;

         --  A scalar subtype S1 is compatible with S2 if their bounds
         --  are static and compatible, even if S1 has dynamic predicates
         --  and is thus non-static. Predicate compatibility has been
         --  checked above.

         elsif not Is_Static_Range (Scalar_Range (T1))
                 or else not Is_Static_Range (Scalar_Range (T2))
         then
            return False;

         --  Base types must match, but we don't check that (should we???) but
         --  we do at least check that both types are real, or both types are
         --  not real.

         elsif Is_Real_Type (T1) /= Is_Real_Type (T2) then
            return False;

         --  Here we check the bounds

         else
            declare
               LB1 : constant Node_Id := Type_Low_Bound  (T1);
               HB1 : constant Node_Id := Type_High_Bound (T1);
               LB2 : constant Node_Id := Type_Low_Bound  (T2);
               HB2 : constant Node_Id := Type_High_Bound (T2);

            begin
               if Is_Real_Type (T1) then
                  return
                    Expr_Value_R (LB1) > Expr_Value_R (HB1)
                      or else
                        (Expr_Value_R (LB2) <= Expr_Value_R (LB1)
                          and then Expr_Value_R (HB1) <= Expr_Value_R (HB2));

               else
                  return
                    Expr_Value (LB1) > Expr_Value (HB1)
                      or else
                        (Expr_Value (LB2) <= Expr_Value (LB1)
                          and then Expr_Value (HB1) <= Expr_Value (HB2));
               end if;
            end;
         end if;

      --  Access types

      elsif Is_Access_Type (T1) then
         return
           (not Is_Constrained (T2)
             or else Subtypes_Statically_Match
                       (Designated_Type (T1), Designated_Type (T2)))
           and then not (Can_Never_Be_Null (T2)
                          and then not Can_Never_Be_Null (T1));

      --  Private types without discriminants can be handled specially.
      --  Predicate matching has been checked above.

      elsif Is_Private_Type (T1)
        and then not Has_Discriminants (T1)
      then
         return not Has_Discriminants (T2);

      --  All other cases

      else
         return
           (Is_Composite_Type (T1) and then not Is_Constrained (T2))
             or else Subtypes_Statically_Match
                       (T1, T2, Formal_Derived_Matching);
      end if;
   end Subtypes_Statically_Compatible;

   -------------------------------
   -- Subtypes_Statically_Match --
   -------------------------------

   --  Subtypes statically match if they have statically matching constraints
   --  (RM 4.9.1(2)). Constraints statically match if there are none, or if
   --  they are the same identical constraint, or if they are static and the
   --  values match (RM 4.9.1(1)).

   --  In addition, in GNAT, the object size (Esize) values of the types must
   --  match if they are set (unless checking an actual for a formal derived
   --  type). The use of 'Object_Size can cause this to be false even if the
   --  types would otherwise match in the Ada 95 RM sense, but this deviation
   --  is adopted by AI12-059 which introduces Object_Size in Ada 2022.

   function Subtypes_Statically_Match
     (T1                      : Entity_Id;
      T2                      : Entity_Id;
      Formal_Derived_Matching : Boolean := False) return Boolean
   is
   begin
      --  A type always statically matches itself

      if T1 = T2 then
         return True;

      --  No match if sizes different (from use of 'Object_Size). This test
      --  is excluded if Formal_Derived_Matching is True, as the base types
      --  can be different in that case and typically have different sizes.

      elsif not Formal_Derived_Matching
        and then Known_Static_Esize (T1)
        and then Known_Static_Esize (T2)
        and then Esize (T1) /= Esize (T2)
      then
         return False;

      --  No match if predicates do not match

      elsif not Predicates_Match (T1, T2) then
         return False;

      --  Scalar types

      elsif Is_Scalar_Type (T1) then

         --  Base types must be the same

         if Base_Type (T1) /= Base_Type (T2) then
            return False;
         end if;

         --  A constrained numeric subtype never matches an unconstrained
         --  subtype, i.e. both types must be constrained or unconstrained.

         --  To understand the requirement for this test, see RM 4.9.1(1).
         --  As is made clear in RM 3.5.4(11), type Integer, for example is
         --  a constrained subtype with constraint bounds matching the bounds
         --  of its corresponding unconstrained base type. In this situation,
         --  Integer and Integer'Base do not statically match, even though
         --  they have the same bounds.

         --  We only apply this test to types in Standard and types that appear
         --  in user programs. That way, we do not have to be too careful about
         --  setting Is_Constrained right for Itypes.

         if Is_Numeric_Type (T1)
           and then Is_Constrained (T1) /= Is_Constrained (T2)
           and then (Scope (T1) = Standard_Standard
                      or else Comes_From_Source (T1))
           and then (Scope (T2) = Standard_Standard
                      or else Comes_From_Source (T2))
         then
            return False;

         --  A generic scalar type does not statically match its base type
         --  (AI-311). In this case we make sure that the formals, which are
         --  first subtypes of their bases, are constrained.

         elsif Is_Generic_Type (T1)
           and then Is_Generic_Type (T2)
           and then Is_Constrained (T1) /= Is_Constrained (T2)
         then
            return False;
         end if;

         --  If there was an error in either range, then just assume the types
         --  statically match to avoid further junk errors.

         if No (Scalar_Range (T1)) or else No (Scalar_Range (T2))
           or else Error_Posted (Scalar_Range (T1))
           or else Error_Posted (Scalar_Range (T2))
         then
            return True;
         end if;

         --  Otherwise both types have bounds that can be compared

         declare
            LB1 : constant Node_Id := Type_Low_Bound  (T1);
            HB1 : constant Node_Id := Type_High_Bound (T1);
            LB2 : constant Node_Id := Type_Low_Bound  (T2);
            HB2 : constant Node_Id := Type_High_Bound (T2);

         begin
            --  If the bounds are the same tree node, then match (common case)

            if LB1 = LB2 and then HB1 = HB2 then
               return True;

            --  Otherwise bounds must be static and identical value

            else
               if not Is_OK_Static_Subtype (T1)
                    or else
                  not Is_OK_Static_Subtype (T2)
               then
                  return False;

               elsif Is_Real_Type (T1) then
                  return
                    Expr_Value_R (LB1) = Expr_Value_R (LB2)
                      and then
                    Expr_Value_R (HB1) = Expr_Value_R (HB2);

               else
                  return
                    Expr_Value (LB1) = Expr_Value (LB2)
                      and then
                    Expr_Value (HB1) = Expr_Value (HB2);
               end if;
            end if;
         end;

      --  Type with discriminants

      elsif Has_Discriminants (T1) or else Has_Discriminants (T2) then

         --  Handle derivations of private subtypes. For example S1 statically
         --  matches the full view of T1 in the following example:

         --      type T1(<>) is new Root with private;
         --      subtype S1 is new T1;
         --      overriding proc P1 (P : S1);
         --    private
         --      type T1 (D : Disc) is new Root with ...

         if Ekind (T2) = E_Record_Subtype_With_Private
           and then not Has_Discriminants (T2)
           and then Partial_View_Has_Unknown_Discr (T1)
           and then Etype (T2) = T1
         then
            return True;

         elsif Ekind (T1) = E_Record_Subtype_With_Private
           and then not Has_Discriminants (T1)
           and then Partial_View_Has_Unknown_Discr (T2)
           and then Etype (T1) = T2
         then
            return True;

         --  Because of view exchanges in multiple instantiations, conformance
         --  checking might try to match a partial view of a type with no
         --  discriminants with a full view that has defaulted discriminants.
         --  In such a case, use the discriminant constraint of the full view,
         --  which must exist because we know that the two subtypes have the
         --  same base type.

         elsif Has_Discriminants (T1) /= Has_Discriminants (T2) then
            if In_Instance then
               if Is_Private_Type (T2)
                 and then Present (Full_View (T2))
                 and then Has_Discriminants (Full_View (T2))
               then
                  return Subtypes_Statically_Match (T1, Full_View (T2));

               elsif Is_Private_Type (T1)
                 and then Present (Full_View (T1))
                 and then Has_Discriminants (Full_View (T1))
               then
                  return Subtypes_Statically_Match (Full_View (T1), T2);

               else
                  return False;
               end if;
            else
               return False;
            end if;
         end if;

         declare

            function Original_Discriminant_Constraint
              (Typ : Entity_Id) return Elist_Id;
            --  Returns Typ's discriminant constraint, or if the constraint
            --  is inherited from an ancestor type, then climbs the parent
            --  types to locate and return the constraint farthest up the
            --  parent chain that Typ's constraint is ultimately inherited
            --  from (stopping before a parent that doesn't impose a constraint
            --  or a parent that has new discriminants). This ensures a proper
            --  result from the equality comparison of Elist_Ids below (as
            --  otherwise, derived types that inherit constraints may appear
            --  to be unequal, because each level of derivation can have its
            --  own copy of the constraint).

            function Original_Discriminant_Constraint
              (Typ : Entity_Id) return Elist_Id
            is
            begin
               if not Has_Discriminants (Typ) then
                  return No_Elist;

               --  If Typ is not a derived type, then directly return the
               --  its constraint.

               elsif not Is_Derived_Type (Typ) then
                  return Discriminant_Constraint (Typ);

               --  If the parent type doesn't have discriminants, doesn't
               --  have a constraint, or has new discriminants, then stop
               --  and return Typ's constraint.

               elsif not Has_Discriminants (Etype (Typ))

                 --  No constraint on the parent type

                 or else not Present (Discriminant_Constraint (Etype (Typ)))
                 or else Is_Empty_Elmt_List
                           (Discriminant_Constraint (Etype (Typ)))

                 --  The parent type defines new discriminants

                 or else
                   (Is_Base_Type (Etype (Typ))
                     and then Present (Discriminant_Specifications
                                         (Parent (Etype (Typ)))))
               then
                  return Discriminant_Constraint (Typ);

               --  Otherwise, make a recursive call on the parent type

               else
                  return Original_Discriminant_Constraint (Etype (Typ));
               end if;
            end Original_Discriminant_Constraint;

            --  Local variables

            DL1 : constant Elist_Id := Original_Discriminant_Constraint (T1);
            DL2 : constant Elist_Id := Original_Discriminant_Constraint (T2);

            DA1 : Elmt_Id;
            DA2 : Elmt_Id;

         begin
            if DL1 = DL2 then
               return True;
            elsif Is_Constrained (T1) /= Is_Constrained (T2) then
               return False;
            end if;

            --  Now loop through the discriminant constraints

            --  Note: the guard here seems necessary, since it is possible at
            --  least for DL1 to be No_Elist. Not clear this is reasonable ???

            if Present (DL1) and then Present (DL2) then
               DA1 := First_Elmt (DL1);
               DA2 := First_Elmt (DL2);
               while Present (DA1) loop
                  declare
                     Expr1 : constant Node_Id := Node (DA1);
                     Expr2 : constant Node_Id := Node (DA2);

                  begin
                     if not Is_OK_Static_Expression (Expr1)
                       or else not Is_OK_Static_Expression (Expr2)
                     then
                        return False;

                        --  If either expression raised a Constraint_Error,
                        --  consider the expressions as matching, since this
                        --  helps to prevent cascading errors.

                     elsif Raises_Constraint_Error (Expr1)
                       or else Raises_Constraint_Error (Expr2)
                     then
                        null;

                     elsif Expr_Value (Expr1) /= Expr_Value (Expr2) then
                        return False;
                     end if;
                  end;

                  Next_Elmt (DA1);
                  Next_Elmt (DA2);
               end loop;
            end if;
         end;

         return True;

      --  A definite type does not match an indefinite or classwide type.
      --  However, a generic type with unknown discriminants may be
      --  instantiated with a type with no discriminants, and conformance
      --  checking on an inherited operation may compare the actual with the
      --  subtype that renames it in the instance.

      elsif Has_Unknown_Discriminants (T1) /= Has_Unknown_Discriminants (T2)
      then
         return
           Is_Generic_Actual_Type (T1) or else Is_Generic_Actual_Type (T2);

      --  Array type

      elsif Is_Array_Type (T1) then

         --  If either subtype is unconstrained then both must be, and if both
         --  are unconstrained then no further checking is needed.

         if not Is_Constrained (T1) or else not Is_Constrained (T2) then
            return not (Is_Constrained (T1) or else Is_Constrained (T2));
         end if;

         --  Both subtypes are constrained, so check that the index subtypes
         --  statically match.

         declare
            Index1 : Node_Id := First_Index (T1);
            Index2 : Node_Id := First_Index (T2);

         begin
            while Present (Index1) loop
               if not
                 Subtypes_Statically_Match (Etype (Index1), Etype (Index2))
               then
                  return False;
               end if;

               Next_Index (Index1);
               Next_Index (Index2);
            end loop;

            return True;
         end;

      elsif Is_Access_Type (T1) then
         if Can_Never_Be_Null (T1) /= Can_Never_Be_Null (T2) then
            return False;

         elsif Ekind (T1) in E_Access_Subprogram_Type
                           | E_Anonymous_Access_Subprogram_Type
         then
            return
              Subtype_Conformant
                (Designated_Type (T1),
                 Designated_Type (T2));
         else
            return
              Subtypes_Statically_Match
                (Designated_Type (T1),
                 Designated_Type (T2))
              and then Is_Access_Constant (T1) = Is_Access_Constant (T2);
         end if;

      --  All other types definitely match

      else
         return True;
      end if;
   end Subtypes_Statically_Match;

   ----------
   -- Test --
   ----------

   function Test (Cond : Boolean) return Uint is
   begin
      if Cond then
         return Uint_1;
      else
         return Uint_0;
      end if;
   end Test;

   ---------------------
   -- Test_Comparison --
   ---------------------

   procedure Test_Comparison
     (Op           : Node_Id;
      Assume_Valid : Boolean;
      True_Result  : out Boolean;
      False_Result : out Boolean)
   is
      Left     : constant Node_Id   := Left_Opnd (Op);
      Left_Typ : constant Entity_Id := Etype (Left);
      Orig_Op  : constant Node_Id   := Original_Node (Op);

      procedure Replacement_Warning (Msg : String);
      --  Emit a warning on a comparison that can be replaced by '='

      -------------------------
      -- Replacement_Warning --
      -------------------------

      procedure Replacement_Warning (Msg : String) is
      begin
         if Constant_Condition_Warnings
           and then Comes_From_Source (Orig_Op)
           and then Is_Integer_Type (Left_Typ)
           and then not Error_Posted (Op)
           and then not Has_Warnings_Off (Left_Typ)
           and then not In_Instance
         then
            Error_Msg_N (Msg, Op);
         end if;
      end Replacement_Warning;

      --  Local variables

      Res : constant Compare_Result :=
              Compile_Time_Compare (Left, Right_Opnd (Op), Assume_Valid);

   --  Start of processing for Test_Comparison

   begin
      case N_Op_Compare (Nkind (Op)) is
         when N_Op_Eq =>
            True_Result  := Res = EQ;
            False_Result := Res = LT or else Res = GT or else Res = NE;

         when N_Op_Ge =>
            True_Result  := Res in Compare_GE;
            False_Result := Res = LT;

            if Res = LE and then Nkind (Orig_Op) = N_Op_Ge then
               Replacement_Warning
                 ("can never be greater than, could replace by ""'=""?c?");
            end if;

         when N_Op_Gt =>
            True_Result  := Res = GT;
            False_Result := Res in Compare_LE;

         when N_Op_Le =>
            True_Result  := Res in Compare_LE;
            False_Result := Res = GT;

            if Res = GE and then Nkind (Orig_Op) = N_Op_Le then
               Replacement_Warning
                 ("can never be less than, could replace by ""'=""?c?");
            end if;

         when N_Op_Lt =>
            True_Result  := Res = LT;
            False_Result := Res in Compare_GE;

         when N_Op_Ne =>
            True_Result  := Res = NE or else Res = GT or else Res = LT;
            False_Result := Res = EQ;
      end case;
   end Test_Comparison;

   ---------------------------------
   -- Test_Expression_Is_Foldable --
   ---------------------------------

   --  One operand case

   procedure Test_Expression_Is_Foldable
     (N    : Node_Id;
      Op1  : Node_Id;
      Stat : out Boolean;
      Fold : out Boolean)
   is
   begin
      Stat := False;
      Fold := False;

      if Debug_Flag_Dot_F and then In_Extended_Main_Source_Unit (N) then
         return;
      end if;

      --  If operand is Any_Type, just propagate to result and do not
      --  try to fold, this prevents cascaded errors.

      if Etype (Op1) = Any_Type then
         Set_Etype (N, Any_Type);
         return;

      --  If operand raises Constraint_Error, then replace node N with the
      --  raise Constraint_Error node, and we are obviously not foldable.
      --  Note that this replacement inherits the Is_Static_Expression flag
      --  from the operand.

      elsif Raises_Constraint_Error (Op1) then
         Rewrite_In_Raise_CE (N, Op1);
         return;

      --  If the operand is not static, then the result is not static, and
      --  all we have to do is to check the operand since it is now known
      --  to appear in a non-static context.

      elsif not Is_Static_Expression (Op1) then
         Check_Non_Static_Context (Op1);
         Fold := Compile_Time_Known_Value (Op1);
         return;

      --   An expression of a formal modular type is not foldable because
      --   the modulus is unknown.

      elsif Is_Modular_Integer_Type (Etype (Op1))
        and then Is_Generic_Type (Etype (Op1))
      then
         Check_Non_Static_Context (Op1);
         return;

      --  Here we have the case of an operand whose type is OK, which is
      --  static, and which does not raise Constraint_Error, we can fold.

      else
         Set_Is_Static_Expression (N);
         Fold := True;
         Stat := True;
      end if;
   end Test_Expression_Is_Foldable;

   --  Two operand case

   procedure Test_Expression_Is_Foldable
     (N        : Node_Id;
      Op1      : Node_Id;
      Op2      : Node_Id;
      Stat     : out Boolean;
      Fold     : out Boolean;
      CRT_Safe : Boolean := False)
   is
      Rstat : constant Boolean := Is_Static_Expression (Op1)
                                    and then
                                  Is_Static_Expression (Op2);

   begin
      Stat := False;
      Fold := False;

      --  Inhibit folding if -gnatd.f flag set

      if Debug_Flag_Dot_F and then In_Extended_Main_Source_Unit (N) then
         return;
      end if;

      --  If either operand is Any_Type, just propagate to result and
      --  do not try to fold, this prevents cascaded errors.

      if Etype (Op1) = Any_Type or else Etype (Op2) = Any_Type then
         Set_Etype (N, Any_Type);
         return;

      --  If left operand raises Constraint_Error, then replace node N with the
      --  Raise_Constraint_Error node, and we are obviously not foldable.
      --  Is_Static_Expression is set from the two operands in the normal way,
      --  and we check the right operand if it is in a non-static context.

      elsif Raises_Constraint_Error (Op1) then
         if not Rstat then
            Check_Non_Static_Context (Op2);
         end if;

         Rewrite_In_Raise_CE (N, Op1);
         Set_Is_Static_Expression (N, Rstat);
         return;

      --  Similar processing for the case of the right operand. Note that we
      --  don't use this routine for the short-circuit case, so we do not have
      --  to worry about that special case here.

      elsif Raises_Constraint_Error (Op2) then
         if not Rstat then
            Check_Non_Static_Context (Op1);
         end if;

         Rewrite_In_Raise_CE (N, Op2);
         Set_Is_Static_Expression (N, Rstat);
         return;

      --  Exclude expressions of a generic modular type, as above

      elsif Is_Modular_Integer_Type (Etype (Op1))
        and then Is_Generic_Type (Etype (Op1))
      then
         Check_Non_Static_Context (Op1);
         return;

      --  If result is not static, then check non-static contexts on operands
      --  since one of them may be static and the other one may not be static.

      elsif not Rstat then
         Check_Non_Static_Context (Op1);
         Check_Non_Static_Context (Op2);

         if CRT_Safe then
            Fold := CRT_Safe_Compile_Time_Known_Value (Op1)
                      and then CRT_Safe_Compile_Time_Known_Value (Op2);
         else
            Fold := Compile_Time_Known_Value (Op1)
                      and then Compile_Time_Known_Value (Op2);
         end if;

         if not Fold
           and then not Is_Modular_Integer_Type (Etype (N))
         then
            case Nkind (N) is
               when N_Op_And =>

                  --  (False and XXX) = (XXX and False) = False

                  Fold :=
                    (Compile_Time_Known_Value (Op1)
                       and then Is_False (Expr_Value (Op1))
                       and then Side_Effect_Free (Op2))
                      or else (Compile_Time_Known_Value (Op2)
                                and then Is_False (Expr_Value (Op2))
                                and then Side_Effect_Free (Op1));

               when N_Op_Or =>

                  --  (True and XXX) = (XXX and True) = True

                  Fold :=
                    (Compile_Time_Known_Value (Op1)
                       and then Is_True (Expr_Value (Op1))
                       and then Side_Effect_Free (Op2))
                      or else (Compile_Time_Known_Value (Op2)
                                and then Is_True (Expr_Value (Op2))
                                and then Side_Effect_Free (Op1));

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

         return;

      --  Else result is static and foldable. Both operands are static, and
      --  neither raises Constraint_Error, so we can definitely fold.

      else
         Set_Is_Static_Expression (N);
         Fold := True;
         Stat := True;
         return;
      end if;
   end Test_Expression_Is_Foldable;

   -------------------
   -- Test_In_Range --
   -------------------

   function Test_In_Range
     (N            : Node_Id;
      Typ          : Entity_Id;
      Assume_Valid : Boolean;
      Fixed_Int    : Boolean;
      Int_Real     : Boolean) return Range_Membership
   is
      Val  : Uint;
      Valr : Ureal;

      pragma Warnings (Off, Assume_Valid);
      --  For now Assume_Valid is unreferenced since the current implementation
      --  always returns Unknown if N is not a compile-time-known value, but we
      --  keep the parameter to allow for future enhancements in which we try
      --  to get the information in the variable case as well.

   begin
      --  If an error was posted on expression, then return Unknown, we do not
      --  want cascaded errors based on some false analysis of a junk node.

      if Error_Posted (N) then
         return Unknown;

      --  Expression that raises Constraint_Error is an odd case. We certainly
      --  do not want to consider it to be in range. It might make sense to
      --  consider it always out of range, but this causes incorrect error
      --  messages about static expressions out of range. So we just return
      --  Unknown, which is always safe.

      elsif Raises_Constraint_Error (N) then
         return Unknown;

      --  Universal types have no range limits, so always in range

      elsif Is_Universal_Numeric_Type (Typ) then
         return In_Range;

      --  Never known if not scalar type. Don't know if this can actually
      --  happen, but our spec allows it, so we must check.

      elsif not Is_Scalar_Type (Typ) then
         return Unknown;

      --  Never known if this is a generic type, since the bounds of generic
      --  types are junk. Note that if we only checked for static expressions
      --  (instead of compile-time-known values) below, we would not need this
      --  check, because values of a generic type can never be static, but they
      --  can be known at compile time.

      elsif Is_Generic_Type (Typ) then
         return Unknown;

      --  Case of a known compile time value, where we can check if it is in
      --  the bounds of the given type.

      elsif Compile_Time_Known_Value (N) then
         declare
            Lo       : constant Node_Id := Type_Low_Bound (Typ);
            Hi       : constant Node_Id := Type_High_Bound (Typ);
            LB_Known : constant Boolean := Compile_Time_Known_Value (Lo);
            HB_Known : constant Boolean := Compile_Time_Known_Value (Hi);

         begin
            --  Fixed point types should be considered as such only if flag
            --  Fixed_Int is set to False.

            if Is_Floating_Point_Type (Typ)
              or else (Is_Fixed_Point_Type (Typ) and then not Fixed_Int)
              or else Int_Real
            then
               Valr := Expr_Value_R (N);

               if LB_Known and HB_Known then
                  if Valr >= Expr_Value_R (Lo)
                       and then
                     Valr <= Expr_Value_R (Hi)
                  then
                     return In_Range;
                  else
                     return Out_Of_Range;
                  end if;

               elsif (LB_Known and then Valr < Expr_Value_R (Lo))
                       or else
                     (HB_Known and then Valr > Expr_Value_R (Hi))
               then
                  return Out_Of_Range;

               else
                  return Unknown;
               end if;

            else
               Val := Expr_Value (N);

               if LB_Known and HB_Known then
                  if Val >= Expr_Value (Lo) and then Val <= Expr_Value (Hi)
                  then
                     return In_Range;
                  else
                     return Out_Of_Range;
                  end if;

               elsif (LB_Known and then Val < Expr_Value (Lo))
                       or else
                     (HB_Known and then Val > Expr_Value (Hi))
               then
                  return Out_Of_Range;

               else
                  return Unknown;
               end if;
            end if;
         end;

      --  Here for value not known at compile time. Case of expression subtype
      --  is Typ or is a subtype of Typ, and we can assume expression is valid.
      --  In this case we know it is in range without knowing its value.

      elsif Assume_Valid
        and then (Etype (N) = Typ or else Is_Subtype_Of (Etype (N), Typ))
      then
         return In_Range;

      --  Another special case. For signed integer types, if the target type
      --  has Is_Known_Valid set, and the source type does not have a larger
      --  size, then the source value must be in range. We exclude biased
      --  types, because they bizarrely can generate out of range values.

      elsif Is_Signed_Integer_Type (Etype (N))
        and then Is_Known_Valid (Typ)
        and then Esize (Etype (N)) <= Esize (Typ)
        and then not Has_Biased_Representation (Etype (N))
      then
         return In_Range;

      --  For all other cases, result is unknown

      else
         return Unknown;
      end if;
   end Test_In_Range;

   --------------
   -- To_Bits --
   --------------

   procedure To_Bits (U : Uint; B : out Bits) is
   begin
      for J in 0 .. B'Last loop
         B (J) := (U / (2 ** J)) mod 2 /= 0;
      end loop;
   end To_Bits;

   --------------------
   -- Why_Not_Static --
   --------------------

   procedure Why_Not_Static (Expr : Node_Id) is
      N   : constant Node_Id := Original_Node (Expr);
      Typ : Entity_Id        := Empty;
      E   : Entity_Id;
      Alt : Node_Id;
      Exp : Node_Id;

      procedure Why_Not_Static_List (L : List_Id);
      --  A version that can be called on a list of expressions. Finds all
      --  non-static violations in any element of the list.

      -------------------------
      -- Why_Not_Static_List --
      -------------------------

      procedure Why_Not_Static_List (L : List_Id) is
         N : Node_Id;
      begin
         N := First (L);
         while Present (N) loop
            Why_Not_Static (N);
            Next (N);
         end loop;
      end Why_Not_Static_List;

   --  Start of processing for Why_Not_Static

   begin
      --  Ignore call on error or empty node

      if No (Expr) or else Nkind (Expr) = N_Error then
         return;
      end if;

      --  Preprocessing for sub expressions

      if Nkind (Expr) in N_Subexpr then

         --  Nothing to do if expression is static

         if Is_OK_Static_Expression (Expr) then
            return;
         end if;

         --  Test for Constraint_Error raised

         if Raises_Constraint_Error (Expr) then

            --  Special case membership to find out which piece to flag

            if Nkind (N) in N_Membership_Test then
               if Raises_Constraint_Error (Left_Opnd (N)) then
                  Why_Not_Static (Left_Opnd (N));
                  return;

               elsif Present (Right_Opnd (N))
                 and then Raises_Constraint_Error (Right_Opnd (N))
               then
                  Why_Not_Static (Right_Opnd (N));
                  return;

               else
                  pragma Assert (Present (Alternatives (N)));

                  Alt := First (Alternatives (N));
                  while Present (Alt) loop
                     if Raises_Constraint_Error (Alt) then
                        Why_Not_Static (Alt);
                        return;
                     else
                        Next (Alt);
                     end if;
                  end loop;
               end if;

            --  Special case a range to find out which bound to flag

            elsif Nkind (N) = N_Range then
               if Raises_Constraint_Error (Low_Bound (N)) then
                  Why_Not_Static (Low_Bound (N));
                  return;

               elsif Raises_Constraint_Error (High_Bound (N)) then
                  Why_Not_Static (High_Bound (N));
                  return;
               end if;

            --  Special case attribute to see which part to flag

            elsif Nkind (N) = N_Attribute_Reference then
               if Raises_Constraint_Error (Prefix (N)) then
                  Why_Not_Static (Prefix (N));
                  return;
               end if;

               Exp := First (Expressions (N));
               while Present (Exp) loop
                  if Raises_Constraint_Error (Exp) then
                     Why_Not_Static (Exp);
                     return;
                  end if;

                  Next (Exp);
               end loop;

            --  Special case a subtype name

            elsif Is_Entity_Name (Expr) and then Is_Type (Entity (Expr)) then
               Error_Msg_NE
                 ("!& is not a static subtype (RM 4.9(26))", N, Entity (Expr));
               return;
            end if;

            --  End of special cases

            Error_Msg_N
              ("!expression raises exception, cannot be static (RM 4.9(34))",
               N);
            return;
         end if;

         --  If no type, then something is pretty wrong, so ignore

         Typ := Etype (Expr);

         if No (Typ) then
            return;
         end if;

         --  Type must be scalar or string type (but allow Bignum, since this
         --  is really a scalar type from our point of view in this diagnosis).

         if not Is_Scalar_Type (Typ)
           and then not Is_String_Type (Typ)
           and then not Is_RTE (Typ, RE_Bignum)
         then
            Error_Msg_N
              ("!static expression must have scalar or string type " &
               "(RM 4.9(2))", N);
            return;
         end if;
      end if;

      --  If we got through those checks, test particular node kind

      case Nkind (N) is

         --  Entity name

         when N_Expanded_Name
            | N_Identifier
            | N_Operator_Symbol
         =>
            E := Entity (N);

            if Is_Named_Number (E) then
               null;

            elsif Ekind (E) = E_Constant then

               --  One case we can give a better message is when we have a
               --  string literal created by concatenating an aggregate with
               --  an others expression.

               Entity_Case : declare
                  CV : constant Node_Id := Constant_Value (E);
                  CO : constant Node_Id := Original_Node (CV);

                  function Is_Aggregate (N : Node_Id) return Boolean;
                  --  See if node N came from an others aggregate, if so
                  --  return True and set Error_Msg_Sloc to aggregate.

                  ------------------
                  -- Is_Aggregate --
                  ------------------

                  function Is_Aggregate (N : Node_Id) return Boolean is
                  begin
                     if Nkind (Original_Node (N)) = N_Aggregate then
                        Error_Msg_Sloc := Sloc (Original_Node (N));
                        return True;

                     elsif Is_Entity_Name (N)
                       and then Ekind (Entity (N)) = E_Constant
                       and then
                         Nkind (Original_Node (Constant_Value (Entity (N)))) =
                                                                  N_Aggregate
                     then
                        Error_Msg_Sloc :=
                          Sloc (Original_Node (Constant_Value (Entity (N))));
                        return True;

                     else
                        return False;
                     end if;
                  end Is_Aggregate;

               --  Start of processing for Entity_Case

               begin
                  if Is_Aggregate (CV)
                    or else (Nkind (CO) = N_Op_Concat
                              and then (Is_Aggregate (Left_Opnd (CO))
                                          or else
                                        Is_Aggregate (Right_Opnd (CO))))
                  then
                     Error_Msg_N ("!aggregate (#) is never static", N);

                  elsif No (CV) or else not Is_Static_Expression (CV) then
                     Error_Msg_NE
                       ("!& is not a static constant (RM 4.9(5))", N, E);
                  end if;
               end Entity_Case;

            elsif Is_Type (E) then
               Error_Msg_NE
                 ("!& is not a static subtype (RM 4.9(26))", N, E);

            elsif E /= Any_Id then
               Error_Msg_NE
                 ("!& is not static constant or named number "
                  & "(RM 4.9(5))", N, E);
            end if;

         --  Binary operator

         when N_Binary_Op
            | N_Membership_Test
            | N_Short_Circuit
         =>
            if Nkind (N) in N_Op_Shift then
               Error_Msg_N
                 ("!shift functions are never static (RM 4.9(6,18))", N);
            else
               Why_Not_Static (Left_Opnd (N));
               Why_Not_Static (Right_Opnd (N));
            end if;

         --  Unary operator

         when N_Unary_Op =>
            Why_Not_Static (Right_Opnd (N));

         --  Attribute reference

         when N_Attribute_Reference =>
            Why_Not_Static_List (Expressions (N));

            E := Etype (Prefix (N));

            if E = Standard_Void_Type then
               return;
            end if;

            --  Special case non-scalar'Size since this is a common error

            if Attribute_Name (N) = Name_Size then
               Error_Msg_N
                 ("!size attribute is only static for static scalar type "
                  & "(RM 4.9(7,8))", N);

            --  Flag array cases

            elsif Is_Array_Type (E) then
               if Attribute_Name (N)
                    not in Name_First | Name_Last | Name_Length
               then
                  Error_Msg_N
                    ("!static array attribute must be Length, First, or Last "
                     & "(RM 4.9(8))", N);

               --  Since we know the expression is not-static (we already
               --  tested for this, must mean array is not static).

               else
                  Error_Msg_N
                    ("!prefix is non-static array (RM 4.9(8))", Prefix (N));
               end if;

               return;

            --  Special case generic types, since again this is a common source
            --  of confusion.

            elsif Is_Generic_Actual_Type (E) or else Is_Generic_Type (E) then
               Error_Msg_N
                 ("!attribute of generic type is never static "
                  & "(RM 4.9(7,8))", N);

            elsif Is_OK_Static_Subtype (E) then
               null;

            elsif Is_Scalar_Type (E) then
               Error_Msg_N
                 ("!prefix type for attribute is not static scalar subtype "
                  & "(RM 4.9(7))", N);

            else
               Error_Msg_N
                 ("!static attribute must apply to array/scalar type "
                  & "(RM 4.9(7,8))", N);
            end if;

         --  String literal

         when N_String_Literal =>
            Error_Msg_N
              ("!subtype of string literal is non-static (RM 4.9(4))", N);

         --  Explicit dereference

         when N_Explicit_Dereference =>
            Error_Msg_N
              ("!explicit dereference is never static (RM 4.9)", N);

         --  Function call

         when N_Function_Call =>
            Why_Not_Static_List (Parameter_Associations (N));

            --  Complain about non-static function call unless we have Bignum
            --  which means that the underlying expression is really some
            --  scalar arithmetic operation.

            if not Is_RTE (Typ, RE_Bignum) then
               Error_Msg_N ("!non-static function call (RM 4.9(6,18))", N);
            end if;

         --  Parameter assocation (test actual parameter)

         when N_Parameter_Association =>
            Why_Not_Static (Explicit_Actual_Parameter (N));

         --  Indexed component

         when N_Indexed_Component =>
            Error_Msg_N ("!indexed component is never static (RM 4.9)", N);

         --  Procedure call

         when N_Procedure_Call_Statement =>
            Error_Msg_N ("!procedure call is never static (RM 4.9)", N);

         --  Qualified expression (test expression)

         when N_Qualified_Expression =>
            Why_Not_Static (Expression (N));

         --  Aggregate

         when N_Aggregate
            | N_Extension_Aggregate
         =>
            Error_Msg_N ("!an aggregate is never static (RM 4.9)", N);

         --  Range

         when N_Range =>
            Why_Not_Static (Low_Bound (N));
            Why_Not_Static (High_Bound (N));

         --  Range constraint, test range expression

         when N_Range_Constraint =>
            Why_Not_Static (Range_Expression (N));

         --  Subtype indication, test constraint

         when N_Subtype_Indication =>
            Why_Not_Static (Constraint (N));

         --  Selected component

         when N_Selected_Component =>
            Error_Msg_N ("!selected component is never static (RM 4.9)", N);

         --  Slice

         when N_Slice =>
            Error_Msg_N ("!slice is never static (RM 4.9)", N);

         when N_Type_Conversion =>
            Why_Not_Static (Expression (N));

            if not Is_Scalar_Type (Entity (Subtype_Mark (N)))
              or else not Is_OK_Static_Subtype (Entity (Subtype_Mark (N)))
            then
               Error_Msg_N
                 ("!static conversion requires static scalar subtype result "
                  & "(RM 4.9(9))", N);
            end if;

         --  Unchecked type conversion

         when N_Unchecked_Type_Conversion =>
            Error_Msg_N
              ("!unchecked type conversion is never static (RM 4.9)", N);

         --  All other cases, no reason to give

         when others =>
            null;
      end case;
   end Why_Not_Static;

end Sem_Eval;
