checks.ads, checks.adb (Selected_Range_Checks): No range check is required for a...
authorThomas Quinot <quinot@adacore.com>
Fri, 6 Apr 2007 09:18:09 +0000 (11:18 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Fri, 6 Apr 2007 09:18:09 +0000 (11:18 +0200)
2007-04-06  Thomas Quinot  <quinot@adacore.com>
    Ed Schonberg  <schonberg@adacore.com>
    Gary Dismukes  <dismukes@adacore.com>

* checks.ads, checks.adb (Selected_Range_Checks): No range check is
required for a conversion between two access-to-unconstrained-array
types.
(Expr_Known_Valid): Validity checks do not apply to discriminants, but
to discriminant constraints on discriminant objects. This rule must
apply as well to discriminants of protected types in private components.
(Null_Exclusion_Static_Checks): If No_Initialization is set on an
object of a null-excluding access type then don't require the
the object declaration to have an expression and don't emit a
run-time check.

From-SVN: r123554

gcc/ada/checks.adb
gcc/ada/checks.ads

index b5b30f79180c41a9a4db3a654a95047c5c18cec9..53c534d9ad27e3f146c547433e9559cb7a50df9c 100644 (file)
@@ -820,11 +820,10 @@ package body Checks is
       Set_Analyzed (Opnd, True);
       Set_Right_Opnd (Opnod, Opnd);
 
-      --  The type of the operation changes to the base type of the check
-      --  type, and we reset the overflow check indication, since clearly
-      --  no overflow is possible now that we are using a double length
-      --  type. We also set the Analyzed flag to avoid a recursive attempt
-      --  to expand the node.
+      --  The type of the operation changes to the base type of the check type,
+      --  and we reset the overflow check indication, since clearly no overflow
+      --  is possible now that we are using a double length type. We also set
+      --  the Analyzed flag to avoid a recursive attempt to expand the node.
 
       Set_Etype             (Opnod, Base_Type (Ctyp));
       Set_Do_Overflow_Check (Opnod, False);
@@ -836,8 +835,8 @@ package body Checks is
       Analyze (Opnd);
       Set_Etype (Opnd, Typ);
 
-      --  In the discrete type case, we directly generate the range check
-      --  for the outer operand. This range check will implement the required
+      --  In the discrete type case, we directly generate the range check for
+      --  the outer operand. This range check will implement the required
       --  overflow check.
 
       if Is_Discrete_Type (Typ) then
@@ -863,16 +862,16 @@ package body Checks is
    -- Apply_Array_Size_Check --
    ----------------------------
 
-   --  The situation is as follows. In GNAT 3 (GCC 2.x), the size in bits
-   --  is computed in 32 bits without an overflow check. That's a real
-   --  problem for Ada. So what we do in GNAT 3 is to approximate the
-   --  size of an array by manually multiplying the element size by the
-   --  number of elements, and comparing that against the allowed limits.
+   --  The situation is as follows. In GNAT 3 (GCC 2.x), the size in bits is
+   --  computed in 32 bits without an overflow check. That's a real problem for
+   --  Ada. So what we do in GNAT 3 is to approximate the size of an array by
+   --  manually multiplying the element size by the number of elements, and
+   --  comparing that against the allowed limits.
 
-   --  In GNAT 5, the size in byte is still computed in 32 bits without
-   --  an overflow check in the dynamic case, but the size in bits is
-   --  computed in 64 bits. We assume that's good enough, and we do not
-   --  bother to generate any front end test.
+   --  In GNAT 5, the size in byte is still computed in 32 bits without an
+   --  overflow check in the dynamic case, but the size in bits is computed in
+   --  64 bits. We assume that's good enough, and we do not bother to generate
+   --  any front end test.
 
    procedure Apply_Array_Size_Check (N : Node_Id; Typ : Entity_Id) is
       Loc  : constant Source_Ptr := Sloc (N);
@@ -893,8 +892,8 @@ package body Checks is
       --  Set false if any index subtye bound is non-static
 
       Umark : constant Uintp.Save_Mark := Uintp.Mark;
-      --  We can throw away all the Uint computations here, since they are
-      --  done only to generate boolean test results.
+      --  We can throw away all the Uint computations here, since they are done
+      --  only to generate boolean test results.
 
       Check_Siz : Uint;
       --  Size to check against
@@ -929,7 +928,6 @@ package body Checks is
                declare
                   F : constant Node_Id :=
                         First (Pragma_Argument_Associations (Decl));
-
                begin
                   return
                     Present (F)
@@ -953,9 +951,11 @@ package body Checks is
    --  Start of processing for Apply_Array_Size_Check
 
    begin
-      --  Do size check on local arrays. We only need this in the GCC 2
-      --  case, since in GCC 3, we expect the back end to properly handle
-      --  things. This routine can be removed when we baseline GNAT 3.
+      --  Do size check on local arrays. We only need this in the GCC 2 case,
+      --  since in GCC 3, we expect the back end to properly handle things.
+      --  This routine can be removed when we baseline GNAT 3.
+
+      --  Shouldn't we remove GCC 2 crud at this stage ???
 
       if Opt.GCC_Version >= 3 then
          return;
@@ -981,10 +981,10 @@ package body Checks is
          return;
       end if;
 
-      --  Look head for pragma interface/import or address clause applying
-      --  to this entity. If found, we suppress the check entirely. For now
-      --  we only look ahead 20 declarations to stop this becoming too slow
-      --  Note that eventually this whole routine gets moved to gigi.
+      --  Look head for pragma interface/import or address clause applying to
+      --  this entity. If found, we suppress the check entirely. For now we
+      --  only look ahead 20 declarations to stop this becoming too slow Note
+      --  that eventually this whole routine gets moved to gigi.
 
       Decl := N;
       for Ctr in 1 .. 20 loop
@@ -996,10 +996,10 @@ package body Checks is
          end if;
       end loop;
 
-      --  First step is to calculate the maximum number of elements. For
-      --  this calculation, we use the actual size of the subtype if it is
-      --  static, and if a bound of a subtype is non-static, we go to the
-      --  bound of the base type.
+      --  First step is to calculate the maximum number of elements. For this
+      --  calculation, we use the actual size of the subtype if it is static,
+      --  and if a bound of a subtype is non-static, we go to the bound of the
+      --  base type.
 
       Siz := Uint_1;
       Indx := First_Index (Typ);
@@ -1008,8 +1008,8 @@ package body Checks is
          Lo := Type_Low_Bound (Xtyp);
          Hi := Type_High_Bound (Xtyp);
 
-         --  If any bound raises constraint error, we will never get this
-         --  far, so there is no need to generate any kind of check.
+         --  If any bound raises constraint error, we will never get this far,
+         --  so there is no need to generate any kind of check.
 
          if Raises_Constraint_Error (Lo)
            or else
@@ -1049,8 +1049,8 @@ package body Checks is
          Check_Siz := Uint_2 ** 31;
       end if;
 
-      --  If we have all static bounds and Siz is too large, then we know
-      --  we know we have a storage error right now, so generate message
+      --  If we have all static bounds and Siz is too large, then we know we
+      --  have a storage error right now, so generate message
 
       if Static and then Siz >= Check_Siz then
          Insert_Action (N,
@@ -1061,8 +1061,8 @@ package body Checks is
          return;
       end if;
 
-      --  Case of component size known at compile time. If the array
-      --  size is definitely in range, then we do not need a check.
+      --  Case of component size known at compile time. If the array size is
+      --  definitely in range, then we do not need a check.
 
       if Known_Esize (Ctyp)
         and then Siz * Esize (Ctyp) < Check_Siz
@@ -1073,9 +1073,9 @@ package body Checks is
 
       --  Here if a dynamic check is required
 
-      --  What we do is to build an expression for the size of the array,
-      --  which is computed as the 'Size of the array component, times
-      --  the size of each dimension.
+      --  What we do is to build an expression for the size of the array, which
+      --  is computed as the 'Size of the array component, times the size of
+      --  each dimension.
 
       Uintp.Release (Umark);
 
@@ -1266,15 +1266,15 @@ package body Checks is
          return;
       end if;
 
-      --  No discriminant checks necessary for an access when expression
-      --  is statically Null. This is not only an optimization, this is
-      --  fundamental because otherwise discriminant checks may be generated
-      --  in init procs for types containing an access to a not-yet-frozen
-      --  record, causing a deadly forward reference.
+      --  No discriminant checks necessary for an access when expression is
+      --  statically Null. This is not only an optimization, it is fundamental
+      --  because otherwise discriminant checks may be generated in init procs
+      --  for types containing an access to a not-yet-frozen record, causing a
+      --  deadly forward reference.
 
-      --  Also, if the expression is of an access type whose designated
-      --  type is incomplete, then the access value must be null and
-      --  we suppress the check.
+      --  Also, if the expression is of an access type whose designated type is
+      --  incomplete, then the access value must be null and we suppress the
+      --  check.
 
       if Nkind (N) = N_Null then
          return;
@@ -1311,9 +1311,9 @@ package body Checks is
          T_Typ := Get_Actual_Subtype (Lhs);
       end if;
 
-      --  Nothing to do if the type is unconstrained (this is the case
-      --  where the actual subtype in the RM sense of N is unconstrained
-      --  and no check is required).
+      --  Nothing to do if the type is unconstrained (this is the case where
+      --  the actual subtype in the RM sense of N is unconstrained and no check
+      --  is required).
 
       if not Is_Constrained (T_Typ) then
          return;
@@ -1333,9 +1333,9 @@ package body Checks is
          return;
       end if;
 
-      --  Suppress checks if the subtypes are the same.
-      --  the check must be preserved in an assignment to a formal, because
-      --  the constraint is given by the actual.
+      --  Suppress checks if the subtypes are the same. the check must be
+      --  preserved in an assignment to a formal, because the constraint is
+      --  given by the actual.
 
       if Nkind (Original_Node (N)) /= N_Allocator
         and then (No (Lhs)
@@ -1349,9 +1349,9 @@ package body Checks is
             return;
          end if;
 
-      --  We can also eliminate checks on allocators with a subtype mark
-      --  that coincides with the context type. The context type may be a
-      --  subtype without a constraint (common case, a generic actual).
+      --  We can also eliminate checks on allocators with a subtype mark that
+      --  coincides with the context type. The context type may be a subtype
+      --  without a constraint (common case, a generic actual).
 
       elsif Nkind (Original_Node (N)) = N_Allocator
         and then Is_Entity_Name (Expression (Original_Node (N)))
@@ -1373,9 +1373,9 @@ package body Checks is
          end;
       end if;
 
-      --  See if we have a case where the types are both constrained, and
-      --  all the constraints are constants. In this case, we can do the
-      --  check successfully at compile time.
+      --  See if we have a case where the types are both constrained, and all
+      --  the constraints are constants. In this case, we can do the check
+      --  successfully at compile time.
 
       --  We skip this check for the case where the node is a rewritten`
       --  allocator, because it already carries the context subtype, and
@@ -1393,10 +1393,10 @@ package body Checks is
 
          begin
             --  S_Typ may not have discriminants in the case where it is a
-            --  private type completed by a default discriminated type. In
-            --  that case, we need to get the constraints from the
-            --  underlying_type. If the underlying type is unconstrained (i.e.
-            --  has no default discriminants) no check is needed.
+            --  private type completed by a default discriminated type. In that
+            --  case, we need to get the constraints from the underlying_type.
+            --  If the underlying type is unconstrained (i.e. has no default
+            --  discriminants) no check is needed.
 
             if Has_Discriminants (S_Typ) then
                Discr := First_Discriminant (S_Typ);
@@ -1578,15 +1578,15 @@ package body Checks is
    -- Apply_Float_Conversion_Check --
    ----------------------------------
 
-   --  Let F and I be the source and target types of the conversion.
-   --  The Ada standard specifies that a floating-point value X is rounded
-   --  to the nearest integer, with halfway cases being rounded away from
-   --  zero. The rounded value of X is checked against I'Range.
+   --  Let F and I be the source and target types of the conversion. The RM
+   --  specifies that a floating-point value X is rounded to the nearest
+   --  integer, with halfway cases being rounded away from zero. The rounded
+   --  value of X is checked against I'Range.
+
+   --  The catch in the above paragraph is that there is no good way to know
+   --  whether the round-to-integer operation resulted in overflow. A remedy is
+   --  to perform a range check in the floating-point domain instead, however:
 
-   --  The catch in the above paragraph is that there is no good way
-   --  to know whether the round-to-integer operation resulted in
-   --  overflow. A remedy is to perform a range check in the floating-point
-   --  domain instead, however:
    --      (1)  The bounds may not be known at compile time
    --      (2)  The check must take into account possible rounding.
    --      (3)  The range of type I may not be exactly representable in F.
@@ -1595,6 +1595,7 @@ package body Checks is
    --      (5)  X may be a NaN, which will fail any comparison
 
    --  The following steps take care of these issues converting X:
+
    --      (1) If either I'First or I'Last is not known at compile time, use
    --          I'Base instead of I in the next three steps and perform a
    --          regular range check against I'Range after conversion.
@@ -1613,36 +1614,40 @@ package body Checks is
      (Ck_Node    : Node_Id;
       Target_Typ : Entity_Id)
    is
-      LB          : constant Node_Id := Type_Low_Bound (Target_Typ);
-      HB          : constant Node_Id := Type_High_Bound (Target_Typ);
+      LB          : constant Node_Id    := Type_Low_Bound (Target_Typ);
+      HB          : constant Node_Id    := Type_High_Bound (Target_Typ);
       Loc         : constant Source_Ptr := Sloc (Ck_Node);
       Expr_Type   : constant Entity_Id  := Base_Type (Etype (Ck_Node));
-      Target_Base : constant Entity_Id  := Implementation_Base_Type
-                                             (Target_Typ);
+      Target_Base : constant Entity_Id  :=
+                      Implementation_Base_Type (Target_Typ);
+
       Max_Bound   : constant Uint := UI_Expon
                                        (Machine_Radix (Expr_Type),
                                         Machine_Mantissa (Expr_Type) - 1) - 1;
       --  Largest bound, so bound plus or minus half is a machine number of F
 
-      Ifirst,
-      Ilast     : Uint;         --  Bounds of integer type
-      Lo, Hi    : Ureal;        --  Bounds to check in floating-point domain
-      Lo_OK,
-      Hi_OK     : Boolean;      --  True iff Lo resp. Hi belongs to I'Range
+      Ifirst, Ilast : Uint;
+      --  Bounds of integer type
+
+      Lo, Hi : Ureal;
+      --  Bounds to check in floating-point domain
 
-      Lo_Chk,
-      Hi_Chk    : Node_Id;      --  Expressions that are False iff check fails
+      Lo_OK, Hi_OK : Boolean;
+      --  True iff Lo resp. Hi belongs to I'Range
 
-      Reason    : RT_Exception_Code;
+      Lo_Chk, Hi_Chk : Node_Id;
+      --  Expressions that are False iff check fails
+
+      Reason : RT_Exception_Code;
 
    begin
       if not Compile_Time_Known_Value (LB)
           or not Compile_Time_Known_Value (HB)
       then
          declare
-            --  First check that the value falls in the range of the base
-            --  type, to prevent overflow during conversion and then
-            --  perform a regular range check against the (dynamic) bounds.
+            --  First check that the value falls in the range of the base type,
+            --  to prevent overflow during conversion and then perform a
+            --  regular range check against the (dynamic) bounds.
 
             Par : constant Node_Id := Parent (Ck_Node);
 
@@ -1734,9 +1739,9 @@ package body Checks is
                      Right_Opnd => Make_Real_Literal (Loc, Hi));
       end if;
 
-      --  If the bounds of the target type are the same as those of the
-      --  base type, the check is an overflow check as a range check is
-      --  not performed in these cases.
+      --  If the bounds of the target type are the same as those of the base
+      --  type, the check is an overflow check as a range check is not
+      --  performed in these cases.
 
       if Expr_Value (Type_Low_Bound (Target_Base)) = Ifirst
         and then Expr_Value (Type_High_Bound (Target_Base)) = Ilast
@@ -1786,8 +1791,8 @@ package body Checks is
    -- Apply_Scalar_Range_Check --
    ------------------------------
 
-   --  Note that Apply_Scalar_Range_Check never turns the Do_Range_Check
-   --  flag off if it is already set on.
+   --  Note that Apply_Scalar_Range_Check never turns the Do_Range_Check flag
+   --  off if it is already set on.
 
    procedure Apply_Scalar_Range_Check
      (Expr       : Node_Id;
@@ -1810,8 +1815,8 @@ package body Checks is
       --  range of the subscript, since we don't know the actual subtype.
 
       Int_Real : Boolean;
-      --  Set to True if Expr should be regarded as a real value
-      --  even though the type of Expr might be discrete.
+      --  Set to True if Expr should be regarded as a real value even though
+      --  the type of Expr might be discrete.
 
       procedure Bad_Value;
       --  Procedure called if value is determined to be out of range
@@ -1834,10 +1839,10 @@ package body Checks is
       if Inside_A_Generic then
          return;
 
-      --  Return if check obviously not needed. Note that we do not check
-      --  for the expander being inactive, since this routine does not
-      --  insert any code, but it does generate useful warnings sometimes,
-      --  which we would like even if we are in semantics only mode.
+      --  Return if check obviously not needed. Note that we do not check for
+      --  the expander being inactive, since this routine does not insert any
+      --  code, but it does generate useful warnings sometimes, which we would
+      --  like even if we are in semantics only mode.
 
       elsif Target_Typ = Any_Type
         or else not Is_Scalar_Type (Target_Typ)
@@ -1901,8 +1906,8 @@ package body Checks is
             then
                return;
 
-            --  If Expr is part of an assignment statement, then check
-            --  left side of assignment if it is an entity name.
+            --  If Expr is part of an assignment statement, then check left
+            --  side of assignment if it is an entity name.
 
             elsif Nkind (Parnt) = N_Assignment_Statement
               and then Is_Entity_Name (Name (Parnt))
@@ -1945,9 +1950,9 @@ package body Checks is
       Is_Unconstrained_Subscr_Ref :=
         Is_Subscr_Ref and then not Is_Constrained (Arr_Typ);
 
-      --  Always do a range check if the source type includes infinities
-      --  and the target type does not include infinities. We do not do
-      --  this if range checks are killed.
+      --  Always do a range check if the source type includes infinities and
+      --  the target type does not include infinities. We do not do this if
+      --  range checks are killed.
 
       if Is_Floating_Point_Type (S_Typ)
         and then Has_Infinities (S_Typ)
@@ -1956,16 +1961,15 @@ package body Checks is
          Enable_Range_Check (Expr);
       end if;
 
-      --  Return if we know expression is definitely in the range of
-      --  the target type as determined by Determine_Range. Right now
-      --  we only do this for discrete types, and not fixed-point or
-      --  floating-point types.
+      --  Return if we know expression is definitely in the range of the target
+      --  type as determined by Determine_Range. Right now we only do this for
+      --  discrete types, and not fixed-point or floating-point types.
 
       --  The additional less-precise tests below catch these cases
 
-      --  Note: skip this if we are given a source_typ, since the point
-      --  of supplying a Source_Typ is to stop us looking at the expression.
-      --  could sharpen this test to be out parameters only ???
+      --  Note: skip this if we are given a source_typ, since the point of
+      --  supplying a Source_Typ is to stop us looking at the expression.
+      --  We could sharpen this test to be out parameters only ???
 
       if Is_Discrete_Type (Target_Typ)
         and then Is_Discrete_Type (Etype (Expr))
@@ -2047,9 +2051,9 @@ package body Checks is
          Bad_Value;
          return;
 
-      --  In the floating-point case, we only do range checks if the
-      --  type is constrained. We definitely do NOT want range checks
-      --  for unconstrained types, since we want to have infinities
+      --  In the floating-point case, we only do range checks if the type is
+      --  constrained. We definitely do NOT want range checks for unconstrained
+      --  types, since we want to have infinities
 
       elsif Is_Floating_Point_Type (S_Typ) then
          if Is_Constrained (S_Typ) then
@@ -2114,9 +2118,8 @@ package body Checks is
             end if;
          end if;
 
-         --  If the item is a conditional raise of constraint error,
-         --  then have a look at what check is being performed and
-         --  ???
+         --  If the item is a conditional raise of constraint error, then have
+         --  a look at what check is being performed and ???
 
          if Nkind (R_Cno) = N_Raise_Constraint_Error
            and then Present (Condition (R_Cno))
@@ -2207,9 +2210,8 @@ package body Checks is
          R_Cno := R_Result (J);
          exit when No (R_Cno);
 
-         --  If the item is a conditional raise of constraint error,
-         --  then have a look at what check is being performed and
-         --  ???
+         --  If the item is a conditional raise of constraint error, then have
+         --  a look at what check is being performed and ???
 
          if Nkind (R_Cno) = N_Raise_Constraint_Error
            and then Present (Condition (R_Cno))
@@ -2229,10 +2231,10 @@ package body Checks is
             if Is_Entity_Name (Cond)
               and then Entity (Cond) = Standard_True
             then
-               --  Since an N_Range is technically not an expression, we
-               --  have to set one of the bounds to C_E and then just flag
-               --  the N_Range. The warning message will point to the
-               --  lower bound and complain about a range, which seems OK.
+               --  Since an N_Range is technically not an expression, we have
+               --  to set one of the bounds to C_E and then just flag the
+               --  N_Range. The warning message will point to the lower bound
+               --  and complain about a range, which seems OK.
 
                if Nkind (Ck_Node) = N_Range then
                   Apply_Compile_Time_Constraint_Error
@@ -2294,10 +2296,10 @@ package body Checks is
       Sub := First (Expressions (Expr));
       while Present (Sub) loop
 
-         --  Check one subscript. Note that we do not worry about
-         --  enumeration type with holes, since we will convert the
-         --  value to a Pos value for the subscript, and that convert
-         --  will do the necessary validity check.
+         --  Check one subscript. Note that we do not worry about enumeration
+         --  type with holes, since we will convert the value to a Pos value
+         --  for the subscript, and that convert will do the necessary validity
+         --  check.
 
          Ensure_Valid (Sub, Holes_OK => True);
 
@@ -2327,18 +2329,18 @@ package body Checks is
       elsif Serious_Errors_Detected > 0 then
          return;
 
-      --  Scalar type conversions of the form Target_Type (Expr) require
-      --  a range check if we cannot be sure that Expr is in the base type
-      --  of Target_Typ and also that Expr is in the range of Target_Typ.
-      --  These are not quite the same condition from an implementation
-      --  point of view, but clearly the second includes the first.
+      --  Scalar type conversions of the form Target_Type (Expr) require a
+      --  range check if we cannot be sure that Expr is in the base type of
+      --  Target_Typ and also that Expr is in the range of Target_Typ. These
+      --  are not quite the same condition from an implementation point of
+      --  view, but clearly the second includes the first.
 
       elsif Is_Scalar_Type (Target_Type) then
          declare
             Conv_OK  : constant Boolean := Conversion_OK (N);
-            --  If the Conversion_OK flag on the type conversion is set
-            --  and no floating point type is involved in the type conversion
-            --  then fixed point values must be read as integral values.
+            --  If the Conversion_OK flag on the type conversion is set and no
+            --  floating point type is involved in the type conversion then
+            --  fixed point values must be read as integral values.
 
             Float_To_Int : constant Boolean :=
                              Is_Floating_Point_Type (Expr_Type)
@@ -2391,7 +2393,6 @@ package body Checks is
 
          begin
             Constraint := First_Elmt (Stored_Constraint (Target_Type));
-
             while Present (Constraint) loop
                Discr_Value := Node (Constraint);
 
@@ -2404,10 +2405,10 @@ package body Checks is
                     and then Scope (Discr) = Base_Type (Expr_Type)
                   then
                      --  Parent is constrained by new discriminant. Obtain
-                     --  Value of original discriminant in expression. If
-                     --  the new discriminant has been used to constrain more
-                     --  than one of the stored discriminants, this will
-                     --  provide the required consistency check.
+                     --  Value of original discriminant in expression. If the
+                     --  new discriminant has been used to constrain more than
+                     --  one of the stored discriminants, this will provide the
+                     --  required consistency check.
 
                      Append_Elmt (
                         Make_Selected_Component (Loc,
@@ -2424,8 +2425,8 @@ package body Checks is
                      return;
                   end if;
 
-               --  Derived type definition has an explicit value for
-               --  this stored discriminant.
+               --  Derived type definition has an explicit value for this
+               --  stored discriminant.
 
                else
                   Append_Elmt
@@ -2450,10 +2451,10 @@ package body Checks is
                 Reason    => CE_Discriminant_Check_Failed));
          end;
 
-      --  For arrays, conversions are applied during expansion, to take
-      --  into accounts changes of representation.  The checks become range
-      --  checks on the base type or length checks on the subtype, depending
-      --  on whether the target type is unconstrained or constrained.
+      --  For arrays, conversions are applied during expansion, to take into
+      --  accounts changes of representation. The checks become range checks on
+      --  the base type or length checks on the subtype, depending on whether
+      --  the target type is unconstrained or constrained.
 
       else
          null;
@@ -2499,11 +2500,11 @@ package body Checks is
       then
          Set_Etype (N, Base_Type (Typ));
 
-      --  Otherwise, replace the attribute node with a type conversion
-      --  node whose expression is the attribute, retyped to universal
-      --  integer, and whose subtype mark is the target type. The call
-      --  to analyze this conversion will set range and overflow checks
-      --  as required for proper detection of an out of range value.
+      --  Otherwise, replace the attribute node with a type conversion node
+      --  whose expression is the attribute, retyped to universal integer, and
+      --  whose subtype mark is the target type. The call to analyze this
+      --  conversion will set range and overflow checks as required for proper
+      --  detection of an out of range value.
 
       else
          Set_Etype    (N, Universal_Integer);
@@ -2545,10 +2546,10 @@ package body Checks is
          Assoc : Node_Id;
 
       begin
-         --  The aggregate has been normalized with named associations. We
-         --  use the Chars field to locate the discriminant to take into
-         --  account discriminants in derived types, which carry the same
-         --  name as those in the parent.
+         --  The aggregate has been normalized with named associations. We use
+         --  the Chars field to locate the discriminant to take into account
+         --  discriminants in derived types, which carry the same name as those
+         --  in the parent.
 
          Assoc := First (Component_Associations (N));
          while Present (Assoc) loop
@@ -2755,10 +2756,10 @@ package body Checks is
       if Range_Checks_Suppressed (Etype (Expr)) then
          return;
 
-      --  Only do this check for expressions that come from source. We
-      --  assume that expander generated assignments explicitly include
-      --  any necessary checks. Note that this is not just an optimization,
-      --  it avoids infinite recursions!
+      --  Only do this check for expressions that come from source. We assume
+      --  that expander generated assignments explicitly include any necessary
+      --  checks. Note that this is not just an optimization, it avoids
+      --  infinite recursions!
 
       elsif not Comes_From_Source (Expr) then
          return;
@@ -2774,8 +2775,8 @@ package body Checks is
       elsif Nkind (Expr) = N_Indexed_Component then
          Apply_Subscript_Validity_Checks (Expr);
 
-         --  Prefix may itself be or contain an indexed component, and
-         --  these subscripts need checking as well
+         --  Prefix may itself be or contain an indexed component, and these
+         --  subscripts need checking as well.
 
          Check_Valid_Lvalue_Subscripts (Prefix (Expr));
       end if;
@@ -2840,7 +2841,7 @@ package body Checks is
               ("null-exclusion must be applied to an access type",
                Error_Node);
 
-         --  Enforce legality rule 3.10 (14/1): A null exclusion can only
+         --  Enforce legality rule RM 3.10(14/1): A null exclusion can only
          --  be applied to a [sub]type that does not exclude null already.
 
          elsif Can_Never_Be_Null (Typ)
@@ -2860,10 +2861,11 @@ package body Checks is
 
       if K = N_Object_Declaration
         and then No (Expression (N))
+        and then not No_Initialization (N)
       then
-         --  Add a an expression that assignates null. This node is needed
-         --  by Apply_Compile_Time_Constraint_Error, that will replace this
-         --  node by a Constraint_Error node.
+         --  Add an expression that assigns null. This node is needed by
+         --  Apply_Compile_Time_Constraint_Error, which will replace this with
+         --  a Constraint_Error node.
 
          Set_Expression (N, Make_Null (Sloc (N)));
          Set_Etype (Expression (N), Etype (Defining_Identifier (N)));
@@ -2922,15 +2924,15 @@ package body Checks is
    begin
       Saved_Checks_TOS := Saved_Checks_TOS + 1;
 
-      --  If stack overflows, kill all checks, that way we know to
-      --  simply reset the number of saved checks to zero on return.
-      --  This should never occur in practice.
+      --  If stack overflows, kill all checks, that way we know to simply reset
+      --  the number of saved checks to zero on return. This should never occur
+      --  in practice.
 
       if Saved_Checks_TOS > Saved_Checks_Stack'Last then
          Kill_All_Checks;
 
-      --  In the normal case, we just make a new stack entry saving
-      --  the current number of saved checks for a later restore.
+      --  In the normal case, we just make a new stack entry saving the current
+      --  number of saved checks for a later restore.
 
       else
          Saved_Checks_Stack (Saved_Checks_TOS) := Num_Saved_Checks;
@@ -2950,15 +2952,15 @@ package body Checks is
    begin
       pragma Assert (Saved_Checks_TOS > 0);
 
-      --  If the saved checks stack overflowed, then we killed all
-      --  checks, so setting the number of saved checks back to
-      --  zero is correct. This should never occur in practice.
+      --  If the saved checks stack overflowed, then we killed all checks, so
+      --  setting the number of saved checks back to zero is correct. This
+      --  should never occur in practice.
 
       if Saved_Checks_TOS > Saved_Checks_Stack'Last then
          Num_Saved_Checks := 0;
 
-      --  In the normal case, restore the number of saved checks
-      --  from the top stack entry.
+      --  In the normal case, restore the number of saved checks from the top
+      --  stack entry.
 
       else
          Num_Saved_Checks := Saved_Checks_Stack (Saved_Checks_TOS);
@@ -2982,13 +2984,13 @@ package body Checks is
    Determine_Range_Cache_N  : array (Cache_Index) of Node_Id;
    Determine_Range_Cache_Lo : array (Cache_Index) of Uint;
    Determine_Range_Cache_Hi : array (Cache_Index) of Uint;
-   --  The above arrays are used to implement a small direct cache
-   --  for Determine_Range calls. Because of the way Determine_Range
-   --  recursively traces subexpressions, and because overflow checking
-   --  calls the routine on the way up the tree, a quadratic behavior
-   --  can otherwise be encountered in large expressions. The cache
-   --  entry for node N is stored in the (N mod Cache_Size) entry, and
-   --  can be validated by checking the actual node value stored there.
+   --  The above arrays are used to implement a small direct cache for
+   --  Determine_Range calls. Because of the way Determine_Range recursively
+   --  traces subexpressions, and because overflow checking calls the routine
+   --  on the way up the tree, a quadratic behavior can otherwise be
+   --  encountered in large expressions. The cache entry for node N is stored
+   --  in the (N mod Cache_Size) entry, and can be validated by checking the
+   --  actual node value stored there.
 
    procedure Determine_Range
      (N  : Node_Id;
@@ -3053,8 +3055,8 @@ package body Checks is
       Lor := No_Uint;
       Hir := No_Uint;
 
-      --  If the type is not discrete, or is undefined, then we can't
-      --  do anything about determining the range.
+      --  If the type is not discrete, or is undefined, then we can't do
+      --  anything about determining the range.
 
       if No (Typ) or else not Is_Discrete_Type (Typ)
         or else Error_Posted (N)
@@ -3067,8 +3069,8 @@ package body Checks is
 
       OK := True;
 
-      --  If value is compile time known, then the possible range is the
-      --  one value that we know this expression definitely has!
+      --  If value is compile time known, then the possible range is the one
+      --  value that we know this expression definitely has!
 
       if Compile_Time_Known_Value (N) then
          Lo := Expr_Value (N);
@@ -3086,16 +3088,16 @@ package body Checks is
          return;
       end if;
 
-      --  Otherwise, start by finding the bounds of the type of the
-      --  expression, the value cannot be outside this range (if it
-      --  is, then we have an overflow situation, which is a separate
-      --  check, we are talking here only about the expression value).
+      --  Otherwise, start by finding the bounds of the type of the expression,
+      --  the value cannot be outside this range (if it is, then we have an
+      --  overflow situation, which is a separate check, we are talking here
+      --  only about the expression value).
 
-      --  We use the actual bound unless it is dynamic, in which case
-      --  use the corresponding base type bound if possible. If we can't
-      --  get a bound then we figure we can't determine the range (a
-      --  peculiar case, that perhaps cannot happen, but there is no
-      --  point in bombing in this optimization circuit.
+      --  We use the actual bound unless it is dynamic, in which case use the
+      --  corresponding base type bound if possible. If we can't get a bound
+      --  then we figure we can't determine the range (a peculiar case, that
+      --  perhaps cannot happen, but there is no point in bombing in this
+      --  optimization circuit.
 
       --  First the low bound
 
@@ -3129,16 +3131,16 @@ package body Checks is
          return;
       end if;
 
-      --  If we have a static subtype, then that may have a tighter bound
-      --  so use the upper bound of the subtype instead in this case.
+      --  If we have a static subtype, then that may have a tighter bound so
+      --  use the upper bound of the subtype instead in this case.
 
       if Compile_Time_Known_Value (Bound) then
          Hi := Expr_Value (Bound);
       end if;
 
-      --  We may be able to refine this value in certain situations. If
-      --  refinement is possible, then Lor and Hir are set to possibly
-      --  tighter bounds, and OK1 is set to True.
+      --  We may be able to refine this value in certain situations. If any
+      --  refinement is possible, then Lor and Hir are set to possibly tighter
+      --  bounds, and OK1 is set to True.
 
       case Nkind (N) is
 
@@ -3166,9 +3168,9 @@ package body Checks is
                Hir := Hi_Left + Hi_Right;
             end if;
 
-         --  Division is tricky. The only case we consider is where the
-         --  right operand is a positive constant, and in this case we
-         --  simply divide the bounds of the left operand
+         --  Division is tricky. The only case we consider is where the right
+         --  operand is a positive constant, and in this case we simply divide
+         --  the bounds of the left operand
 
          when N_Op_Divide =>
             if OK_Operands then
@@ -3183,8 +3185,8 @@ package body Checks is
                end if;
             end if;
 
-         --  For binary subtraction, get range of each operand and do
-         --  the worst case subtraction to get the result range.
+         --  For binary subtraction, get range of each operand and do the worst
+         --  case subtraction to get the result range.
 
          when N_Op_Subtract =>
             if OK_Operands then
@@ -3192,8 +3194,8 @@ package body Checks is
                Hir := Hi_Left - Lo_Right;
             end if;
 
-         --  For MOD, if right operand is a positive constant, then
-         --  result must be in the allowable range of mod results.
+         --  For MOD, if right operand is a positive constant, then result must
+         --  be in the allowable range of mod results.
 
          when N_Op_Mod =>
             if OK_Operands then
@@ -3214,8 +3216,8 @@ package body Checks is
                end if;
             end if;
 
-         --  For REM, if right operand is a positive constant, then
-         --  result must be in the allowable range of mod results.
+         --  For REM, if right operand is a positive constant, then result must
+         --  be in the allowable range of mod results.
 
          when N_Op_Rem =>
             if OK_Operands then
@@ -3340,8 +3342,8 @@ package body Checks is
 
             end case;
 
-         --  For type conversion from one discrete type to another, we
-         --  can refine the range using the converted value.
+         --  For type conversion from one discrete type to another, we can
+         --  refine the range using the converted value.
 
          when N_Type_Conversion =>
             Determine_Range (Expression (N), OK1, Lor, Hir);
@@ -3499,10 +3501,10 @@ package body Checks is
          pg (N);
       end if;
 
-      --  Nothing to do if the range of the result is known OK. We skip
-      --  this for conversions, since the caller already did the check,
-      --  and in any case the condition for deleting the check for a
-      --  type conversion is different in any case.
+      --  Nothing to do if the range of the result is known OK. We skip this
+      --  for conversions, since the caller already did the check, and in any
+      --  case the condition for deleting the check for a type conversion is
+      --  different in any case.
 
       if Nkind (N) /= N_Type_Conversion then
          Determine_Range (N, OK, Lo, Hi);
@@ -3536,12 +3538,12 @@ package body Checks is
          end if;
       end if;
 
-      --  If not in optimizing mode, set flag and we are done. We are also
-      --  done (and just set the flag) if the type is not a discrete type,
-      --  since it is not worth the effort to eliminate checks for other
-      --  than discrete types. In addition, we take this same path if we
-      --  have stored the maximum number of checks possible already (a
-      --  very unlikely situation, but we do not want to blow up!)
+      --  If not in optimizing mode, set flag and we are done. We are also done
+      --  (and just set the flag) if the type is not a discrete type, since it
+      --  is not worth the effort to eliminate checks for other than discrete
+      --  types. In addition, we take this same path if we have stored the
+      --  maximum number of checks possible already (a very unlikely situation,
+      --  but we do not want to blow up!)
 
       if Optimization_Level = 0
         or else not Is_Discrete_Type (Etype (N))
@@ -3616,10 +3618,10 @@ package body Checks is
          w ("  Target_Type = Empty");
       end if;
 
-   --  If we get an exception, then something went wrong, probably because
-   --  of an error in the structure of the tree due to an incorrect program.
-   --  Or it may be a bug in the optimization circuit. In either case the
-   --  safest thing is simply to set the check flag unconditionally.
+   --  If we get an exception, then something went wrong, probably because of
+   --  an error in the structure of the tree due to an incorrect program. Or it
+   --  may be a bug in the optimization circuit. In either case the safest
+   --  thing is simply to set the check flag unconditionally.
 
    exception
       when others =>
@@ -3645,9 +3647,8 @@ package body Checks is
       P    : Node_Id;
 
    begin
-      --  Return if unchecked type conversion with range check killed.
-      --  In this case we never set the flag (that's what Kill_Range_Check
-      --  is all about!)
+      --  Return if unchecked type conversion with range check killed. In this
+      --  case we never set the flag (that's what Kill_Range_Check is about!)
 
       if Nkind (N) = N_Unchecked_Type_Conversion
         and then Kill_Range_Check (N)
@@ -3699,12 +3700,12 @@ package body Checks is
          pg (N);
       end if;
 
-      --  If not in optimizing mode, set flag and we are done. We are also
-      --  done (and just set the flag) if the type is not a discrete type,
-      --  since it is not worth the effort to eliminate checks for other
-      --  than discrete types. In addition, we take this same path if we
-      --  have stored the maximum number of checks possible already (a
-      --  very unlikely situation, but we do not want to blow up!)
+      --  If not in optimizing mode, set flag and we are done. We are also done
+      --  (and just set the flag) if the type is not a discrete type, since it
+      --  is not worth the effort to eliminate checks for other than discrete
+      --  types. In addition, we take this same path if we have stored the
+      --  maximum number of checks possible already (a very unlikely situation,
+      --  but we do not want to blow up!)
 
       if Optimization_Level = 0
         or else No (Etype (N))
@@ -3746,17 +3747,17 @@ package body Checks is
                Atyp := Designated_Type (Atyp);
 
                --  If the prefix is an access to an unconstrained array,
-               --  perform check unconditionally: it depends on the bounds
-               --  of an object and we cannot currently recognize whether
-               --  the test may be redundant.
+               --  perform check unconditionally: it depends on the bounds of
+               --  an object and we cannot currently recognize whether the test
+               --  may be redundant.
 
                if not Is_Constrained (Atyp) then
                   Set_Do_Range_Check (N, True);
                   return;
                end if;
 
-            --  Ditto if the prefix is an explicit dereference whose
-            --  designated type is unconstrained.
+            --  Ditto if the prefix is an explicit dereference whose designated
+            --  type is unconstrained.
 
             elsif Nkind (Prefix (P)) = N_Explicit_Dereference
               and then not Is_Constrained (Atyp)
@@ -3855,10 +3856,10 @@ package body Checks is
          pg (Ttyp);
       end if;
 
-   --  If we get an exception, then something went wrong, probably because
-   --  of an error in the structure of the tree due to an incorrect program.
-   --  Or it may be a bug in the optimization circuit. In either case the
-   --  safest thing is simply to set the check flag unconditionally.
+   --  If we get an exception, then something went wrong, probably because of
+   --  an error in the structure of the tree due to an incorrect program. Or
+   --  it may be a bug in the optimization circuit. In either case the safest
+   --  thing is simply to set the check flag unconditionally.
 
    exception
       when others =>
@@ -3889,9 +3890,9 @@ package body Checks is
       elsif Range_Or_Validity_Checks_Suppressed (Expr) then
          return;
 
-      --  No check required if expression is from the expander, we assume
-      --  the expander will generate whatever checks are needed. Note that
-      --  this is not just an optimization, it avoids infinite recursions!
+      --  No check required if expression is from the expander, we assume the
+      --  expander will generate whatever checks are needed. Note that this is
+      --  not just an optimization, it avoids infinite recursions!
 
       --  Unchecked conversions must be checked, unless they are initialized
       --  scalar values, as in a component assignment in an init proc.
@@ -3910,8 +3911,8 @@ package body Checks is
       elsif Expr_Known_Valid (Expr) then
          return;
 
-      --  Ignore case of enumeration with holes where the flag is set not
-      --  to worry about holes, since no special validity check is needed
+      --  Ignore case of enumeration with holes where the flag is set not to
+      --  worry about holes, since no special validity check is needed
 
       elsif Is_Enumeration_Type (Typ)
         and then Has_Non_Standard_Rep (Typ)
@@ -3979,10 +3980,10 @@ package body Checks is
                   P := Parent (N);
                end if;
 
-               --  Only need to worry if we are argument of a procedure
-               --  call since functions don't have out parameters. If this
-               --  is an indirect or dispatching call, get signature from
-               --  the subprogram type.
+               --  Only need to worry if we are argument of a procedure call
+               --  since functions don't have out parameters. If this is an
+               --  indirect or dispatching call, get signature from the
+               --  subprogram type.
 
                if Nkind (P) = N_Procedure_Call_Statement then
                   L := Parameter_Associations (P);
@@ -3994,18 +3995,17 @@ package body Checks is
                      E := Etype (Name (P));
                   end if;
 
-                  --  Only need to worry if there are indeed actuals, and
-                  --  if this could be a procedure call, otherwise we cannot
-                  --  get a match (either we are not an argument, or the
-                  --  mode of the formal is not OUT). This test also filters
-                  --  out the generic case.
+                  --  Only need to worry if there are indeed actuals, and if
+                  --  this could be a procedure call, otherwise we cannot get a
+                  --  match (either we are not an argument, or the mode of the
+                  --  formal is not OUT). This test also filters out the
+                  --  generic case.
 
                   if Is_Non_Empty_List (L)
                     and then Is_Subprogram (E)
                   then
-                     --  This is the loop through parameters, looking to
-                     --  see if there is an OUT parameter for which we are
-                     --  the argument.
+                     --  This is the loop through parameters, looking for an
+                     --  OUT parameter for which we are the argument.
 
                      F := First_Formal (E);
                      A := First (L);
@@ -4036,14 +4036,13 @@ package body Checks is
       Typ : constant Entity_Id := Etype (Expr);
 
    begin
-      --  Non-scalar types are always considered valid, since they never
-      --  give rise to the issues of erroneous or bounded error behavior
-      --  that are the concern. In formal reference manual terms the
-      --  notion of validity only applies to scalar types. Note that
-      --  even when packed arrays are represented using modular types,
-      --  they are still arrays semantically, so they are also always
-      --  valid (in particular, the unused bits can be random rubbish
-      --  without affecting the validity of the array value).
+      --  Non-scalar types are always considered valid, since they never give
+      --  rise to the issues of erroneous or bounded error behavior that are
+      --  the concern. In formal reference manual terms the notion of validity
+      --  only applies to scalar types. Note that even when packed arrays are
+      --  represented using modular types, they are still arrays semantically,
+      --  so they are also always valid (in particular, the unused bits can be
+      --  random rubbish without affecting the validity of the array value).
 
       if not Is_Scalar_Type (Typ) or else Is_Packed_Array_Type (Typ) then
          return True;
@@ -4061,8 +4060,8 @@ package body Checks is
       then
          return True;
 
-      --  If the expression is the value of an object that is known to
-      --  be valid, then clearly the expression value itself is valid.
+      --  If the expression is the value of an object that is known to be
+      --  valid, then clearly the expression value itself is valid.
 
       elsif Is_Entity_Name (Expr)
         and then Is_Known_Valid (Entity (Expr))
@@ -4073,17 +4072,18 @@ package body Checks is
       --  of a discriminant gets checked when the object is built. Within the
       --  record, we consider it valid, and it is important to do so, since
       --  otherwise we can try to generate bogus validity checks which
-      --  reference discriminants out of scope.
+      --  reference discriminants out of scope. Discriminants of concurrent
+      --  types are excluded for the same reason.
 
       elsif Is_Entity_Name (Expr)
-        and then Ekind (Entity (Expr)) = E_Discriminant
+        and then Denotes_Discriminant (Expr, Check_Concurrent => True)
       then
          return True;
 
-      --  If the type is one for which all values are known valid, then
-      --  we are sure that the value is valid except in the slightly odd
-      --  case where the expression is a reference to a variable whose size
-      --  has been explicitly set to a value greater than the object size.
+      --  If the type is one for which all values are known valid, then we are
+      --  sure that the value is valid except in the slightly odd case where
+      --  the expression is a reference to a variable whose size has been
+      --  explicitly set to a value greater than the object size.
 
       elsif Is_Known_Valid (Typ) then
          if Is_Entity_Name (Expr)
@@ -4131,8 +4131,8 @@ package body Checks is
             return True;
          end if;
 
-      --  The result of a membership test is always valid, since it is true
-      --  or false, there are no other possibilities.
+      --  The result of a membership test is always valid, since it is true or
+      --  false, there are no other possibilities.
 
       elsif Nkind (Expr) in N_Membership_Test then
          return True;
@@ -4247,8 +4247,8 @@ package body Checks is
          return;
       end if;
 
-      --  Come here with expression of appropriate form, check if
-      --  entity is an appropriate one for our purposes.
+      --  Come here with expression of appropriate form, check if entity is an
+      --  appropriate one for our purposes.
 
       if (Ekind (Ent) = E_Variable
             or else
@@ -4295,7 +4295,7 @@ package body Checks is
    ---------------------------------
 
    --  Note: the code for this procedure is derived from the
-   --  emit_discriminant_check routine a-trans.c v1.659.
+   --  Emit_Discriminant_Check Routine in trans.c.
 
    procedure Generate_Discriminant_Check (N : Node_Id) is
       Loc  : constant Source_Ptr := Sloc (N);
@@ -4323,9 +4323,9 @@ package body Checks is
       --  List of arguments for function call
 
       Formal : Entity_Id;
-      --  Keep track of the formal corresponding to the actual we build
-      --  for each discriminant, in order to be able to perform the
-      --  necessary type conversions.
+      --  Keep track of the formal corresponding to the actual we build for
+      --  each discriminant, in order to be able to perform the necessary type
+      --  conversions.
 
       Scomp : Node_Id;
       --  Selected component reference for checking function argument
@@ -4363,10 +4363,10 @@ package body Checks is
       if Is_Tagged_Type (Scope (Orig_Comp)) then
          Pref_Type := Scope (Orig_Comp);
 
-      --  For an untagged derived type, use the discriminants of the
-      --  parent which have been renamed in the derivation, possibly
-      --  by a one-to-many discriminant constraint.
-      --  For non-tagged type, initially get the Etype of the prefix
+      --  For an untagged derived type, use the discriminants of the parent
+      --  which have been renamed in the derivation, possibly by a one-to-many
+      --  discriminant constraint. For non-tagged type, initially get the Etype
+      --  of the prefix
 
       else
          if Is_Derived_Type (Pref_Type)
@@ -4415,8 +4415,8 @@ package body Checks is
 
          --  Manually analyze and resolve this selected component. We really
          --  want it just as it appears above, and do not want the expander
-         --  playing discriminal games etc with this reference. Then we
-         --  append the argument to the list we are gathering.
+         --  playing discriminal games etc with this reference. Then we append
+         --  the argument to the list we are gathering.
 
          Set_Etype (Scomp, Etype (Real_Discr));
          Set_Analyzed (Scomp, True);
@@ -4465,8 +4465,8 @@ package body Checks is
          if Do_Range_Check (Sub) then
             Set_Do_Range_Check (Sub, False);
 
-            --  Force evaluation except for the case of a simple name of
-            --  non-volatile entity.
+            --  Force evaluation except for the case of a simple name of a
+            --  non-volatile entity.
 
             if not Is_Entity_Name (Sub)
               or else Treat_As_Volatile (Entity (Sub))
@@ -4479,12 +4479,12 @@ package body Checks is
 
             --    Base_Type(Sub) not in array'range (subscript)
 
-            --  Note that the reason we generate the conversion to the
-            --  base type here is that we definitely want the range check
-            --  to take place, even if it looks like the subtype is OK.
-            --  Optimization considerations that allow us to omit the
-            --  check have already been taken into account in the setting
-            --  of the Do_Range_Check flag earlier on.
+            --  Note that the reason we generate the conversion to the base
+            --  type here is that we definitely want the range check to take
+            --  place, even if it looks like the subtype is OK. Optimization
+            --  considerations that allow us to omit the check have already
+            --  been taken into account in the setting of the Do_Range_Check
+            --  flag earlier on.
 
             if Ind = 1 then
                Num := No_List;
@@ -4527,14 +4527,14 @@ package body Checks is
       Target_Base_Type : constant Entity_Id  := Base_Type (Target_Type);
 
    begin
-      --  First special case, if the source type is already within the
-      --  range of the target type, then no check is needed (probably we
-      --  should have stopped Do_Range_Check from being set in the first
-      --  place, but better late than later in preventing junk code!
+      --  First special case, if the source type is already within the range
+      --  of the target type, then no check is needed (probably we should have
+      --  stopped Do_Range_Check from being set in the first place, but better
+      --  late than later in preventing junk code!
 
-      --  We do NOT apply this if the source node is a literal, since in
-      --  this case the literal has already been labeled as having the
-      --  subtype of the target.
+      --  We do NOT apply this if the source node is a literal, since in this
+      --  case the literal has already been labeled as having the subtype of
+      --  the target.
 
       if In_Subrange_Of (Source_Type, Target_Type)
         and then not
@@ -4561,9 +4561,9 @@ package body Checks is
          Force_Evaluation (N);
       end if;
 
-      --  The easiest case is when Source_Base_Type and Target_Base_Type
-      --  are the same since in this case we can simply do a direct
-      --  check of the value of N against the bounds of Target_Type.
+      --  The easiest case is when Source_Base_Type and Target_Base_Type are
+      --  the same since in this case we can simply do a direct check of the
+      --  value of N against the bounds of Target_Type.
 
       --    [constraint_error when N not in Target_Type]
 
@@ -4615,20 +4615,19 @@ package body Checks is
                            Attribute_Name => Name_Last)))),
              Reason => Reason));
 
-      --  Note that at this stage we now that the Target_Base_Type is
-      --  not in the range of the Source_Base_Type (since even the
-      --  Target_Type itself is not in this range). It could still be
-      --  the case that the Source_Type is in range of the target base
-      --  type, since we have not checked that case.
+      --  Note that at this stage we now that the Target_Base_Type is not in
+      --  the range of the Source_Base_Type (since even the Target_Type itself
+      --  is not in this range). It could still be the case that Source_Type is
+      --  in range of the target base type since we have not checked that case.
 
-      --  If that is the case, we can freely convert the source to the
-      --  target, and then test the target result against the bounds.
+      --  If that is the case, we can freely convert the source to the target,
+      --  and then test the target result against the bounds.
 
       elsif In_Subrange_Of (Source_Type, Target_Base_Type) then
 
-         --  We make a temporary to hold the value of the converted
-         --  value (converted to the base type), and then we will
-         --  do the test against this temporary.
+         --  We make a temporary to hold the value of the converted value
+         --  (converted to the base type), and then we will do the test against
+         --  this temporary.
 
          --     Tnn : constant Target_Base_Type := Target_Base_Type (N);
          --     [constraint_error when Tnn not in Target_Type]
@@ -4680,8 +4679,8 @@ package body Checks is
             --  know that the source is not shorter than the target (otherwise
             --  the source base type would be in the target base type range).
 
-            --  In other words, the unsigned type is either the same size
-            --  as the target, or it is larger. It cannot be smaller.
+            --  In other words, the unsigned type is either the same size as
+            --  the target, or it is larger. It cannot be smaller.
 
             pragma Assert
               (Esize (Source_Base_Type) >= Esize (Target_Base_Type));
@@ -4761,27 +4760,26 @@ package body Checks is
             pragma Assert (not Is_Unsigned_Type (Source_Base_Type)
                              and then Is_Unsigned_Type (Target_Base_Type));
 
-            --  If the source is signed and the target is unsigned, then
-            --  we know that the target is not shorter than the source
-            --  (otherwise the target base type would be in the source
-            --  base type range).
+            --  If the source is signed and the target is unsigned, then we
+            --  know that the target is not shorter than the source (otherwise
+            --  the target base type would be in the source base type range).
 
-            --  In other words, the unsigned type is either the same size
-            --  as the target, or it is larger. It cannot be smaller.
+            --  In other words, the unsigned type is either the same size as
+            --  the target, or it is larger. It cannot be smaller.
 
-            --  Clearly we have an error if the source value is negative
-            --  since no unsigned type can have negative values. If the
-            --  source type is non-negative, then the check can be done
-            --  using the target type.
+            --  Clearly we have an error if the source value is negative since
+            --  no unsigned type can have negative values. If the source type
+            --  is non-negative, then the check can be done using the target
+            --  type.
 
             --    Tnn : constant Target_Base_Type (N) := Target_Type;
 
             --    [constraint_error
             --       when N < 0 or else Tnn not in Target_Type];
 
-            --  We turn off all checks for the conversion of N to the
-            --  target base type, since we generate the explicit check
-            --  to ensure that the value is non-negative
+            --  We turn off all checks for the conversion of N to the target
+            --  base type, since we generate the explicit check to ensure that
+            --  the value is non-negative
 
             declare
                Tnn : constant Entity_Id :=
@@ -4818,9 +4816,9 @@ package body Checks is
                    Reason => Reason)),
                  Suppress => All_Checks);
 
-               --  Set the Etype explicitly, because Insert_Actions may
-               --  have placed the declaration in the freeze list for an
-               --  enclosing construct, and thus it is not analyzed yet.
+               --  Set the Etype explicitly, because Insert_Actions may have
+               --  placed the declaration in the freeze list for an enclosing
+               --  construct, and thus it is not analyzed yet.
 
                Set_Etype (Tnn, Target_Base_Type);
                Rewrite (N, New_Occurrence_Of (Tnn, Loc));
@@ -4944,9 +4942,9 @@ package body Checks is
                      (not Range_Checks_Suppressed (Suppress_Typ));
 
    begin
-      --  For now we just return if Checks_On is false, however this should
-      --  be enhanced to check for an always True value in the condition
-      --  and to generate a compilation warning???
+      --  For now we just return if Checks_On is false, however this should be
+      --  enhanced to check for an always True value in the condition and to
+      --  generate a compilation warning???
 
       if not Expander_Active or else not Checks_On then
          return;
@@ -5193,9 +5191,9 @@ package body Checks is
          w ("Kill_All_Checks");
       end if;
 
-      --  We reset the number of saved checks to zero, and also modify
-      --  all stack entries for statement ranges to indicate that the
-      --  number of checks at each level is now zero.
+      --  We reset the number of saved checks to zero, and also modify all
+      --  stack entries for statement ranges to indicate that the number of
+      --  checks at each level is now zero.
 
       Num_Saved_Checks := 0;
 
@@ -5621,7 +5619,6 @@ package body Checks is
             end if;
 
             return N;
-
          end if;
       end Get_E_Length;
 
@@ -5638,7 +5635,6 @@ package body Checks is
                Duplicate_Subexpr_No_Checks (N, Name_Req => True),
              Expressions => New_List (
                Make_Integer_Literal (Loc, Indx)));
-
       end Get_N_Length;
 
       -------------------
@@ -5655,7 +5651,6 @@ package body Checks is
            Make_Op_Ne (Loc,
              Left_Opnd  => Get_E_Length (Typ, Indx),
              Right_Opnd => Get_E_Length (Exptyp, Indx));
-
       end Length_E_Cond;
 
       -------------------
@@ -5672,9 +5667,12 @@ package body Checks is
            Make_Op_Ne (Loc,
              Left_Opnd  => Get_E_Length (Typ, Indx),
              Right_Opnd => Get_N_Length (Expr, Indx));
-
       end Length_N_Cond;
 
+      -----------------
+      -- Same_Bounds --
+      -----------------
+
       function Same_Bounds (L : Node_Id; R : Node_Id) return Boolean is
       begin
          return
@@ -5807,12 +5805,11 @@ package body Checks is
                   Ref_Node : Node_Id;
 
                begin
-
-                  --  At the library level, we need to ensure that the
-                  --  type of the object is elaborated before the check
-                  --  itself is emitted. This is only done if the object
-                  --  is in the current compilation unit, otherwise the
-                  --  type is frozen and elaborated in its unit.
+                  --  At the library level, we need to ensure that the type of
+                  --  the object is elaborated before the check itself is
+                  --  emitted. This is only done if the object is in the
+                  --  current compilation unit, otherwise the type is frozen
+                  --  and elaborated in its unit.
 
                   if Is_Itype (Exptyp)
                     and then
@@ -5904,8 +5901,8 @@ package body Checks is
             --  do not evaluate it more than once.
 
             --  Here Ck_Node is the original expression, or more properly the
-            --  result of applying Duplicate_Expr to the original tree,
-            --  forcing the result to be a name.
+            --  result of applying Duplicate_Expr to the original tree, forcing
+            --  the result to be a name.
 
             else
                declare
@@ -6080,12 +6077,14 @@ package body Checks is
 
       begin
          if Nkind (LB) = N_Identifier
-           and then Ekind (Entity (LB)) = E_Discriminant then
+           and then Ekind (Entity (LB)) = E_Discriminant
+         then
             LB := New_Occurrence_Of (Discriminal (Entity (LB)), Loc);
          end if;
 
          if Nkind (HB) = N_Identifier
-           and then Ekind (Entity (HB)) = E_Discriminant then
+           and then Ekind (Entity (HB)) = E_Discriminant
+         then
             HB := New_Occurrence_Of (Discriminal (Entity (HB)), Loc);
          end if;
 
@@ -6239,12 +6238,11 @@ package body Checks is
          elsif Nkind (Bound) = N_Integer_Literal then
             return Make_Integer_Literal (Loc, Intval (Bound));
 
-         --  Case of a bound that has been rewritten to an
-         --  N_Raise_Constraint_Error node because it is an out-of-range
-         --  value. We may not call Duplicate_Subexpr on this node because
-         --  an N_Raise_Constraint_Error is not side effect free, and we may
-         --  not assume that we are in the proper context to remove side
-         --  effects on it at the point of reference.
+         --  Case of a bound rewritten to an N_Raise_Constraint_Error node
+         --  because it is an out-of-range value. Duplicate_Subexpr cannot be
+         --  called on this node because an N_Raise_Constraint_Error is not
+         --  side effect free, and we may not assume that we are in the proper
+         --  context to remove side effects on it at the point of reference.
 
          elsif Nkind (Bound) = N_Raise_Constraint_Error then
             return New_Copy_Tree (Bound);
@@ -6305,7 +6303,6 @@ package body Checks is
                Make_Op_Gt (Loc,
                  Left_Opnd => Get_E_First_Or_Last (Exptyp, Indx, Name_Last),
                  Right_Opnd  => Get_E_First_Or_Last (Typ, Indx, Name_Last)));
-
       end Range_E_Cond;
 
       ------------------------
@@ -6505,18 +6502,17 @@ package body Checks is
                   HB : Node_Id := High_Bound (Ck_Node);
 
                begin
-
-                  --  If either bound is a discriminant and we are within
-                  --  the record declaration, it is a use of the discriminant
-                  --  in a constraint of a component, and nothing can be
-                  --  checked here. The check will be emitted within the
-                  --  init proc. Before then, the discriminal has no real
-                  --  meaning. Similarly, if the entity is a discriminal,
-                  --  there is no check to perform yet.
-
-                  --  The same holds within a discriminated synchronized
-                  --  type, where the discriminant may constrain a component
-                  --  or an entry family.
+                  --  If either bound is a discriminant and we are within the
+                  --  record declaration, it is a use of the discriminant in a
+                  --  constraint of a component, and nothing can be checked
+                  --  here. The check will be emitted within the init proc.
+                  --  Before then, the discriminal has no real meaning.
+                  --  Similarly, if the entity is a discriminal, there is no
+                  --  check to perform yet.
+
+                  --  The same holds within a discriminated synchronized type,
+                  --  where the discriminant may constrain a component or an
+                  --  entry family.
 
                   if Nkind (LB) = N_Identifier
                     and then Denotes_Discriminant (LB, True)
@@ -6557,7 +6553,6 @@ package body Checks is
                           Right_Opnd => Duplicate_Subexpr_No_Checks (LB)),
                       Right_Opnd => Cond);
                end;
-
             end if;
          end;
 
@@ -6748,21 +6743,23 @@ package body Checks is
             end if;
 
          else
-            --  Generate an Action to check that the bounds of the
-            --  source value are within the constraints imposed by the
-            --  target type for a conversion to an unconstrained type.
-            --  Rule is 4.6(38).
-
-            if Nkind (Parent (Ck_Node)) = N_Type_Conversion then
+            --  For a conversion to an unconstrained array type, generate an
+            --  Action to check that the bounds of the source value are within
+            --  the constraints imposed by the target type (RM 4.6(38)). No
+            --  check is needed for a conversion to an access to unconstrained
+            --  array type, as 4.6(24.15/2) requires the designated subtypes
+            --  of the two access types to statically match.
+
+            if Nkind (Parent (Ck_Node)) = N_Type_Conversion
+              and then not Do_Access
+            then
                declare
                   Opnd_Index : Node_Id;
                   Targ_Index : Node_Id;
 
                begin
-                  Opnd_Index
-                    := First_Index (Get_Actual_Subtype (Ck_Node));
+                  Opnd_Index := First_Index (Get_Actual_Subtype (Ck_Node));
                   Targ_Index := First_Index (T_Typ);
-
                   while Opnd_Index /= Empty loop
                      if Nkind (Opnd_Index) = N_Range then
                         if Is_In_Range
@@ -6773,7 +6770,7 @@ package body Checks is
                         then
                            null;
 
-                           --  If null range, no check needed
+                        --  If null range, no check needed
 
                         elsif
                           Compile_Time_Known_Value (High_Bound (Opnd_Index))
index bc7e947595a012e88b7a0772d683e3d3e01b866d..84012a16a60ba83bb10d938f9c52751286ca799d 100644 (file)
@@ -264,6 +264,12 @@ package Checks is
    --                this node is further examined depends on the setting of
    --                the parameter Source_Typ, as described below.
 
+   --    ??? Apply_Length_Check and Apply_Range_Check do not have an Expr
+   --        formal
+
+   --    ??? Apply_Length_Check and Apply_Range_Check have a Ck_Node formal
+   --        which is undocumented, is it the same as Expr?
+
    --    Target_Typ  The target type on which the check is to be based. For
    --                example, if we have a scalar range check, then the check
    --                is that we are in range of this type.
@@ -311,7 +317,7 @@ package Checks is
      (Ck_Node    : Node_Id;
       Target_Typ : Entity_Id;
       Source_Typ : Entity_Id := Empty);
-   --  For an Node of kind N_Range, constructs a range check action that tests
+   --  For a Node of kind N_Range, constructs a range check action that tests
    --  first that the range is not null and then that the range is contained in
    --  the Target_Typ range.
    --