aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/checks.adb
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2014-07-31 11:58:06 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2014-07-31 11:58:06 +0200
commitb7c874a77cff436d8730223b80ffa53d3dba05c3 (patch)
tree7e48781eb00a70bb90b702a951747b8b6beaa8e8 /gcc/ada/checks.adb
parente1360f501bd99b198e997e1ce2f22231dfc9b69d (diff)
downloadgcc-b7c874a77cff436d8730223b80ffa53d3dba05c3.zip
gcc-b7c874a77cff436d8730223b80ffa53d3dba05c3.tar.gz
gcc-b7c874a77cff436d8730223b80ffa53d3dba05c3.tar.bz2
[multiple changes]
2014-07-31 Robert Dewar <dewar@adacore.com> * checks.adb (Enable_Overflow_Check): More precise setting of Do_Overflow_Check flag for division. 2014-07-31 Eric Botcazou <ebotcazou@adacore.com> * exp_aggr.adb (Aggr_Assignment_OK_For_Backend): Reject packed array types with implementation type. 2014-07-31 Hristian Kirtchev <kirtchev@adacore.com> * sem_ch10.adb (Process_State): Remove local variable Name. Add local variable Decl. Partially declare an abstract state by generating an entity and storing it in the state declaration. * sem_prag.adb (Create_Abstract_State): Fully declare a semi-declared abstract state. From-SVN: r213335
Diffstat (limited to 'gcc/ada/checks.adb')
-rw-r--r--gcc/ada/checks.adb57
1 files changed, 50 insertions, 7 deletions
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index 3fb352e..f75f1c6 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -1795,6 +1795,8 @@ package body Checks is
if Do_Overflow_Check (N)
and then not Overflow_Checks_Suppressed (Etype (N))
then
+ Set_Do_Overflow_Check (N, False);
+
-- Test for extremely annoying case of xxx'First divided by -1
-- for division of signed integer types (only overflow case).
@@ -1855,6 +1857,8 @@ package body Checks is
-- it is a Division_Check and not an Overflow_Check.
if Do_Division_Check (N) then
+ Set_Do_Division_Check (N, False);
+
if (not ROK) or else (Rlo <= 0 and then 0 <= Rhi) then
Insert_Action (N,
Make_Raise_Constraint_Error (Loc,
@@ -5110,6 +5114,8 @@ package body Checks is
Lo : Uint;
Hi : Uint;
+ Do_Ovflow_Check : Boolean;
+
begin
if Debug_Flag_CC then
w ("Enable_Overflow_Check for node ", Int (N));
@@ -5187,15 +5193,52 @@ package body Checks is
-- c) The alternative is a lot of special casing in this routine
-- which would partially duplicate Determine_Range processing.
- if OK
- and then Lo > Expr_Value (Type_Low_Bound (Typ))
- and then Hi < Expr_Value (Type_High_Bound (Typ))
- then
- if Debug_Flag_CC then
- w ("No overflow check required");
+ if OK then
+ Do_Ovflow_Check := True;
+
+ -- Note that the following checks are quite deliberately > and <
+ -- rather than >= and <= as explained above.
+
+ if Lo > Expr_Value (Type_Low_Bound (Typ))
+ and then
+ Hi < Expr_Value (Type_High_Bound (Typ))
+ then
+ Do_Ovflow_Check := False;
+
+ -- Despite the comments above, it is worth dealing specially with
+ -- division specially. The only case where integer division can
+ -- overflow is (largest negative number) / (-1). So we will do
+ -- an extra range analysis to see if this is possible.
+
+ elsif Nkind (N) = N_Op_Divide then
+ Determine_Range
+ (Left_Opnd (N), OK, Lo, Hi, Assume_Valid => True);
+
+ if OK and then Lo > Expr_Value (Type_Low_Bound (Typ)) then
+ Do_Ovflow_Check := False;
+
+ else
+ Determine_Range
+ (Right_Opnd (N), OK, Lo, Hi, Assume_Valid => True);
+
+ if OK and then (Lo > Uint_Minus_1
+ or else
+ Hi < Uint_Minus_1)
+ then
+ Do_Ovflow_Check := False;
+ end if;
+ end if;
end if;
- return;
+ -- If no overflow check required, we are done
+
+ if not Do_Ovflow_Check then
+ if Debug_Flag_CC then
+ w ("No overflow check required");
+ end if;
+
+ return;
+ end if;
end if;
end if;