summaryrefslogtreecommitdiff
path: root/gcc/ada/checks.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/checks.adb')
-rw-r--r--gcc/ada/checks.adb92
1 files changed, 57 insertions, 35 deletions
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index d74a05c11fe..075eb14caeb 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -34,6 +34,7 @@ with Exp_Pakd; use Exp_Pakd;
with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util;
with Elists; use Elists;
+with Expander; use Expander;
with Eval_Fat; use Eval_Fat;
with Freeze; use Freeze;
with Lib; use Lib;
@@ -1272,8 +1273,7 @@ package body Checks is
Apply_Range_Check (N, Typ);
end if;
- elsif (Is_Record_Type (Typ)
- or else Is_Private_Type (Typ))
+ elsif (Is_Record_Type (Typ) or else Is_Private_Type (Typ))
and then Has_Discriminants (Base_Type (Typ))
and then Is_Constrained (Typ)
then
@@ -6709,10 +6709,12 @@ package body Checks is
-- to be done in bignum mode), and the determined ranges of the operands.
-- After possible rewriting of a constituent subexpression node, a call is
- -- made to reanalyze the node after setting Analyzed to False. To avoid a
- -- recursive call into the whole overflow apparatus, and important rule for
- -- this reanalysis call is that either Do_Overflow_Check must be False, or
- -- if it is set, then the overflow checking mode must be temporarily set
+ -- made to either reexpand the node (if nothing has changed) or reanalyze
+ -- the node (if it has been modified by the overflow check processing).
+ -- The Analyzed_flag is set False before the reexpand/reanalyze. To avoid
+ -- a recursive call into the whole overflow apparatus, and important rule
+ -- for this call is that either Do_Overflow_Check must be False, or if
+ -- it is set, then the overflow checking mode must be temporarily set
-- to Checked/Suppressed. Either step will avoid the unwanted recursion.
procedure Minimize_Eliminate_Overflow_Checks
@@ -6761,6 +6763,17 @@ package body Checks is
-- range, then we must convert such operands back to the result type.
-- This switch is properly set only when Bignum_Operands is False.
+ procedure Reexpand (C : Suppressed_Or_Checked);
+ -- This is called when we have not modifed the node, so we do not need
+ -- to reanalyze it. But we do want to reexpand it in either CHECKED
+ -- or SUPPRESSED mode (as indicated by the argument C) to get proper
+ -- expansion. It is important that we reset the mode to SUPPRESSED or
+ -- CHECKED, since if we leave it in MINIMIZED or ELIMINATED mode we
+ -- would reenter this routine recursively which would not be good!
+ -- Note that this is not just an optimization, testing has showed up
+ -- several complex cases in which renalyzing an already analyzed node
+ -- causes incorrect behavior.
+
function In_Result_Range return Boolean;
-- Returns True iff Lo .. Hi are within range of the result type
@@ -6813,6 +6826,24 @@ package body Checks is
end if;
end Min;
+ --------------
+ -- Reexpand --
+ --------------
+
+ procedure Reexpand (C : Suppressed_Or_Checked) is
+ Svg : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_General;
+ Sva : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_Assertions;
+ begin
+ Scope_Suppress.Overflow_Checks_General := C;
+ Scope_Suppress.Overflow_Checks_Assertions := C;
+ Set_Analyzed (N, False);
+ Expand (N);
+ Scope_Suppress.Overflow_Checks_General := Svg;
+ Scope_Suppress.Overflow_Checks_Assertions := Sva;
+ end Reexpand;
+
-- Start of processing for Minimize_Eliminate_Overflow_Checks
begin
@@ -6890,13 +6921,13 @@ package body Checks is
-- If we have no Long_Long_Integer operands, then we are in result
-- range, since it means that none of our operands felt the need
-- to worry about overflow (otherwise it would have already been
- -- converted to long long integer or bignum). We reanalyze to
- -- complete the expansion of the if expression
+ -- converted to long long integer or bignum). We reexpand to
+ -- complete the expansion of the if expression (but we do not
+ -- need to reanalyze).
elsif not Long_Long_Integer_Operands then
Set_Do_Overflow_Check (N, False);
- Set_Analyzed (N, False);
- Analyze_And_Resolve (N, Suppress => Overflow_Check);
+ Reexpand (Suppressed);
-- Otherwise convert us to long long integer mode. Note that we
-- don't need any further overflow checking at this level.
@@ -6953,14 +6984,13 @@ package body Checks is
-- that none of our dependent expressions could raise overflow.
-- In this case, we simply return with no changes except for
-- resetting the overflow flag, since we are done with overflow
- -- checks for this node. We will reset the Analyzed flag so that
- -- we will properly reexpand and get the needed expansion for
- -- the case expression.
+ -- checks for this node. We will reexpand to get the needed
+ -- expansion for the case expression, but we do not need to
+ -- renalyze, since nothing has changed.
if not (Bignum_Operands or Long_Long_Integer_Operands) then
Set_Do_Overflow_Check (N, False);
- Set_Analyzed (N, False);
- Analyze_And_Resolve (N, Suppress => Overflow_Check);
+ Reexpand (Suppressed);
-- Otherwise we are going to rebuild the case expression using
-- either bignum or long long integer operands throughout.
@@ -7381,18 +7411,20 @@ package body Checks is
end case;
end if;
- -- If we know we are in the result range, and we do not have Bignum
- -- operands or Long_Long_Integer operands, we can just renalyze with
- -- overflow checks turned off (since we know we cannot have overflow).
- -- As always the reanalysis is required to complete expansion of the
- -- operator, and we prevent recursion by suppressing the check.
+ -- Here for the case where we have not rewritten anything (no bignum
+ -- operands or long long integer operands), and we know the result If we
+ -- know we are in the result range, and we do not have Bignum operands
+ -- or Long_Long_Integer operands, we can just reexpand with overflow
+ -- checks turned off (since we know we cannot have overflow). As always
+ -- the reexpansion is required to complete expansion of the operator,
+ -- but we do not need to reanalyze, and we prevent recursion by
+ -- suppressing the check,
if not (Bignum_Operands or Long_Long_Integer_Operands)
and then In_Result_Range
then
Set_Do_Overflow_Check (N, False);
- Set_Analyzed (N, False);
- Analyze_And_Resolve (N, Suppress => Overflow_Check);
+ Reexpand (Suppressed);
return;
-- Here we know that we are not in the result range, and in the general
@@ -7427,20 +7459,10 @@ package body Checks is
-- eliminated overflow processing which is not what we want. Here
-- we are at the top level, and we need a check against the result
-- mode (i.e. we want to use Checked mode). So do exactly that!
+ -- Also, we have not modified the node, so this is a case where
+ -- we need to reexpand, but not reanalyze.
- declare
- Svg : constant Overflow_Check_Type :=
- Scope_Suppress.Overflow_Checks_General;
- Sva : constant Overflow_Check_Type :=
- Scope_Suppress.Overflow_Checks_Assertions;
- begin
- Scope_Suppress.Overflow_Checks_General := Checked;
- Scope_Suppress.Overflow_Checks_Assertions := Checked;
- Analyze_And_Resolve (N);
- Scope_Suppress.Overflow_Checks_General := Svg;
- Scope_Suppress.Overflow_Checks_Assertions := Sva;
- end;
-
+ Reexpand (Checked);
return;
-- Cases where we do the operation in Bignum mode. This happens either