aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/checks.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/checks.adb')
-rw-r--r--gcc/ada/checks.adb70
1 files changed, 42 insertions, 28 deletions
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index d01db36..38b6ea4 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -2692,15 +2692,24 @@ 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.
+ -- Special checks for floating-point type
- if Is_Floating_Point_Type (S_Typ)
- and then Has_Infinities (S_Typ)
- and then not Has_Infinities (Target_Typ)
- then
- Enable_Range_Check (Expr);
+ if Is_Floating_Point_Type (S_Typ) then
+
+ -- Always do a range check if the source type includes infinities and
+ -- the target type does not include infinities. We do not do this if
+ -- range checks are killed.
+
+ if Has_Infinities (S_Typ)
+ and then not Has_Infinities (Target_Typ)
+ then
+ Enable_Range_Check (Expr);
+
+ -- Always do a range check for operators if option set
+
+ elsif Check_Float_Overflow and then Nkind (Expr) in N_Op then
+ Enable_Range_Check (Expr);
+ end if;
end if;
-- Return if we know expression is definitely in the range of the target
@@ -2780,15 +2789,14 @@ package body Checks is
-- only if this is not a conversion between integer and real types.
if not Is_Unconstrained_Subscr_Ref
- and then
- Is_Discrete_Type (S_Typ) = Is_Discrete_Type (Target_Typ)
+ and then Is_Discrete_Type (S_Typ) = Is_Discrete_Type (Target_Typ)
and then
(In_Subrange_Of (S_Typ, Target_Typ, Fixed_Int)
or else
Is_In_Range (Expr, Target_Typ,
Assume_Valid => True,
- Fixed_Int => Fixed_Int,
- Int_Real => Int_Real))
+ Fixed_Int => Fixed_Int,
+ Int_Real => Int_Real))
then
return;
@@ -2800,12 +2808,18 @@ package body Checks is
Bad_Value;
return;
+ -- Floating-point case
-- In the floating-point case, we only do range checks if the type is
-- constrained. We definitely do NOT want range checks for unconstrained
-- types, since we want to have infinities
elsif Is_Floating_Point_Type (S_Typ) then
- if Is_Constrained (S_Typ) then
+
+ -- Normally, we only do range checks if the type is constrained. We do
+ -- NOT want range checks for unconstrained types, since we want to have
+ -- infinities. Override this decision in Check_Float_Overflow mode.
+
+ if Is_Constrained (S_Typ) or else Check_Float_Overflow then
Enable_Range_Check (Expr);
end if;
@@ -5650,22 +5664,24 @@ package body Checks is
-- 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.
+ -- late than never in preventing junk code!
if In_Subrange_Of (Source_Type, Target_Type)
+
+ -- We do NOT apply this if the source node is a literal, since in this
+ -- case the literal has already been labeled as having the subtype of
+ -- the target.
+
and then not
- (Nkind (N) = N_Integer_Literal
- or else
- Nkind (N) = N_Real_Literal
+ (Nkind_In (N, N_Integer_Literal, N_Real_Literal, N_Character_Literal)
or else
- Nkind (N) = N_Character_Literal
- or else
- (Is_Entity_Name (N)
- and then Ekind (Entity (N)) = E_Enumeration_Literal))
+ (Is_Entity_Name (N)
+ and then Ekind (Entity (N)) = E_Enumeration_Literal))
+
+ -- Also do not apply this for floating-point if Check_Float_Overflow
+
+ and then not
+ (Is_Floating_Point_Type (Source_Type) and Check_Float_Overflow)
then
return;
end if;
@@ -5675,9 +5691,7 @@ package body Checks is
-- reference). Such a double evaluation is always a potential source
-- of inefficiency, and is functionally incorrect in the volatile case.
- if not Is_Entity_Name (N)
- or else Treat_As_Volatile (Entity (N))
- then
+ if not Is_Entity_Name (N) or else Treat_As_Volatile (Entity (N)) then
Force_Evaluation (N);
end if;