diff options
Diffstat (limited to 'gcc/ada/checks.adb')
| -rw-r--r-- | gcc/ada/checks.adb | 70 |
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; |
