summaryrefslogtreecommitdiffstats
path: root/gcc/ada/checks.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2007-04-06 09:18:09 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2007-04-06 09:18:09 +0000
commitfeff2f05aae7de498420ca7c4b3989251c650548 (patch)
treede49bf424086aff1103408245a1df50cff482b5d /gcc/ada/checks.adb
parent20c9f7d4b2ef7132e406f977822f9be49ccc16d1 (diff)
downloadppe42-gcc-feff2f05aae7de498420ca7c4b3989251c650548.tar.gz
ppe42-gcc-feff2f05aae7de498420ca7c4b3989251c650548.zip
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123554 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/checks.adb')
-rw-r--r--gcc/ada/checks.adb767
1 files changed, 382 insertions, 385 deletions
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index b5b30f79180..53c534d9ad2 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -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
- -- a 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))
OpenPOWER on IntegriCloud