Commit 4b1c4f20 by Robert Dewar Committed by Arnaud Charlet

checks.adb (Apply_Arithmetic_Overflow_Checked_Suppressed): New name for…

checks.adb (Apply_Arithmetic_Overflow_Checked_Suppressed): New name for Apply_Arithmetic_Overflow_Normal

2012-10-02  Robert Dewar  <dewar@adacore.com>

	* checks.adb (Apply_Arithmetic_Overflow_Checked_Suppressed):
	New name for Apply_Arithmetic_Overflow_Normal
	(Apply_Arithmetic_Overflow_Minimized_Eliminated):
	Add handling for conditional expressions
	(Is_Signed_Integer_Arithmetic_Op): Now includes conditional
	expressions (Minimize_Eliminate_Overflow_Checks): Handle
	conditional expressions.
	* checks.ads: Minor comment fixes.
	* exp_ch4.adb (Expand_N_Case_Expression): Call
	Apply_Arithmetic_Overflow_Check (Expand_N_Conditional_Expression):
	Call Apply_Arithmetic_Overflow_Check
	* s-bignum.adb (Normalize): Remove incorrect precondition.
	* sem_res.adb (Resolve_Case_Expression): Set Do_Overflow_Check
	flag (Resolve_Conditional_Expression): Set Do_Overflow_Check flag.
	* sinfo.adb: Add Do_Overflow_Check for conditional expressions.
	* sinfo.ads: Minor documentation updates.

From-SVN: r191964
parent 2492305b
2012-10-02 Robert Dewar <dewar@adacore.com>
* checks.adb (Apply_Arithmetic_Overflow_Checked_Suppressed):
New name for Apply_Arithmetic_Overflow_Normal
(Apply_Arithmetic_Overflow_Minimized_Eliminated):
Add handling for conditional expressions
(Is_Signed_Integer_Arithmetic_Op): Now includes conditional
expressions (Minimize_Eliminate_Overflow_Checks): Handle
conditional expressions.
* checks.ads: Minor comment fixes.
* exp_ch4.adb (Expand_N_Case_Expression): Call
Apply_Arithmetic_Overflow_Check (Expand_N_Conditional_Expression):
Call Apply_Arithmetic_Overflow_Check
* s-bignum.adb (Normalize): Remove incorrect precondition.
* sem_res.adb (Resolve_Case_Expression): Set Do_Overflow_Check
flag (Resolve_Conditional_Expression): Set Do_Overflow_Check flag.
* sinfo.adb: Add Do_Overflow_Check for conditional expressions.
* sinfo.ads: Minor documentation updates.
2012-10-02 Ed Schonberg <schonberg@adacore.com> 2012-10-02 Ed Schonberg <schonberg@adacore.com>
* exp_ch4.adb (Expand_N_Case_Expression): Do not introduce * exp_ch4.adb (Expand_N_Case_Expression): Do not introduce
......
...@@ -135,13 +135,14 @@ package Checks is ...@@ -135,13 +135,14 @@ package Checks is
-- larger than the overlaid object. -- larger than the overlaid object.
procedure Apply_Arithmetic_Overflow_Check (N : Node_Id); procedure Apply_Arithmetic_Overflow_Check (N : Node_Id);
-- Given a binary arithmetic operator (+ - *) expand a software integer -- Handle overflow checking for an arithmetic operator. Also handles the
-- overflow check using range checks on a larger checking type or a call -- cases of ELIMINATED and MINIMIZED overflow checking mode. If the mode
-- to an appropriate runtime routine. This is used for all three operators -- is one of the latter two, then this routine can also be called with
-- for the signed integer case, and for +/- in the fixed-point case. The -- a conditional expression node to make sure that we properly handle
-- check is expanded only if Software_Overflow_Checking is enabled and -- overflow checking for dependent expressions. This routine handles
-- Do_Overflow_Check is set on node N. Note that divide is handled -- front end vs back end overflow checks (in the front end case it expands
-- separately using Apply_Arithmetic_Divide_Overflow_Check. -- the necessary check). Note that divide is handled separately using
-- Apply_Arithmetic_Divide_Overflow_Check.
procedure Apply_Constraint_Check procedure Apply_Constraint_Check
(N : Node_Id; (N : Node_Id;
......
...@@ -4776,6 +4776,18 @@ package body Exp_Ch4 is ...@@ -4776,6 +4776,18 @@ package body Exp_Ch4 is
Fexp : Node_Id; Fexp : Node_Id;
begin begin
-- If Do_Overflow_Check is set, it means we are in MINIMIZED/ELIMINATED
-- mode, and all we do is to call Apply_Arithmetic_Overflow_Check to
-- ensure proper overflow handling for the dependent expressions. The
-- checks circuitry will rewrite the case expression in this case with
-- Do_Overflow_Checks off. so that when that rewritten node arrives back
-- here, then we will do the full expansion.
if Do_Overflow_Check (N) then
Apply_Arithmetic_Overflow_Check (N);
return;
end if;
-- We expand -- We expand
-- case X is when A => AX, when B => BX ... -- case X is when A => AX, when B => BX ...
...@@ -5204,6 +5216,15 @@ package body Exp_Ch4 is ...@@ -5204,6 +5216,15 @@ package body Exp_Ch4 is
-- the same approach as a C conditional expression. -- the same approach as a C conditional expression.
else else
-- If Do_Overflow_Check is set it means we have a signed intger type
-- in MINIMIZED or ELIMINATED mode, so we apply an overflow check to
-- the if expression (to make sure that overflow checking is properly
-- handled for dependent expressions).
if Do_Overflow_Check (N) then
Apply_Arithmetic_Overflow_Check (N);
end if;
return; return;
end if; end if;
......
...@@ -104,8 +104,7 @@ package body System.Bignums is ...@@ -104,8 +104,7 @@ package body System.Bignums is
function Normalize function Normalize
(X : Digit_Vector; (X : Digit_Vector;
Neg : Boolean := False) return Bignum Neg : Boolean := False) return Bignum;
with Pre => X'First = 1;
-- Given a digit vector and sign, allocate and construct a Bignum value. -- Given a digit vector and sign, allocate and construct a Bignum value.
-- Note that X may have leading zeroes which must be removed, and if the -- Note that X may have leading zeroes which must be removed, and if the
-- result is zero, the sign is forced positive. -- result is zero, the sign is forced positive.
......
...@@ -5941,6 +5941,16 @@ package body Sem_Res is ...@@ -5941,6 +5941,16 @@ package body Sem_Res is
Set_Etype (N, Typ); Set_Etype (N, Typ);
Eval_Case_Expression (N); Eval_Case_Expression (N);
-- If we still have a case expression, and overflow checks are enabled
-- in MINIMIZED or ELIMINATED modes, then set Do_Overflow_Check to
-- ensure that we handle overflow for dependent expressions.
if Nkind (N) = N_Case_Expression
and then Overflow_Check_Mode (Typ) in Minimized_Or_Eliminated
then
Set_Do_Overflow_Check (N);
end if;
end Resolve_Case_Expression; end Resolve_Case_Expression;
------------------------------- -------------------------------
...@@ -6134,8 +6144,9 @@ package body Sem_Res is ...@@ -6134,8 +6144,9 @@ package body Sem_Res is
Resolve (Then_Expr, Typ); Resolve (Then_Expr, Typ);
Then_Typ := Etype (Then_Expr); Then_Typ := Etype (Then_Expr);
-- When the "then" and "else" expressions are of a scalar type, insert -- When the "then" expression is of a scalar type different from the
-- a conversion to ensure the generation of a constraint check. -- result type, then insert a conversion to ensure the generation of
-- a constraint check.
if Is_Scalar_Type (Then_Typ) if Is_Scalar_Type (Then_Typ)
and then Then_Typ /= Typ and then Then_Typ /= Typ
...@@ -6174,6 +6185,16 @@ package body Sem_Res is ...@@ -6174,6 +6185,16 @@ package body Sem_Res is
Set_Etype (N, Typ); Set_Etype (N, Typ);
Eval_Conditional_Expression (N); Eval_Conditional_Expression (N);
-- If we still have a conditional expression, and overflow checks are
-- enabled in MINIMIZED or ELIMINATED modes, then set Do_Overflow_Check
-- to ensure that we handle overflow for dependent expressions.
if Nkind (N) = N_Conditional_Expression
and then Overflow_Check_Mode (Typ) in Minimized_Or_Eliminated
then
Set_Do_Overflow_Check (N);
end if;
end Resolve_Conditional_Expression; end Resolve_Conditional_Expression;
----------------------------------------- -----------------------------------------
......
...@@ -927,6 +927,8 @@ package body Sinfo is ...@@ -927,6 +927,8 @@ package body Sinfo is
pragma Assert (False pragma Assert (False
or else NT (N).Nkind in N_Op or else NT (N).Nkind in N_Op
or else NT (N).Nkind = N_Attribute_Reference or else NT (N).Nkind = N_Attribute_Reference
or else NT (N).Nkind = N_Case_Expression
or else NT (N).Nkind = N_Conditional_Expression
or else NT (N).Nkind = N_Type_Conversion); or else NT (N).Nkind = N_Type_Conversion);
return Flag17 (N); return Flag17 (N);
end Do_Overflow_Check; end Do_Overflow_Check;
...@@ -3998,6 +4000,8 @@ package body Sinfo is ...@@ -3998,6 +4000,8 @@ package body Sinfo is
pragma Assert (False pragma Assert (False
or else NT (N).Nkind in N_Op or else NT (N).Nkind in N_Op
or else NT (N).Nkind = N_Attribute_Reference or else NT (N).Nkind = N_Attribute_Reference
or else NT (N).Nkind = N_Case_Expression
or else NT (N).Nkind = N_Conditional_Expression
or else NT (N).Nkind = N_Type_Conversion); or else NT (N).Nkind = N_Type_Conversion);
Set_Flag17 (N, Val); Set_Flag17 (N, Val);
end Set_Do_Overflow_Check; end Set_Do_Overflow_Check;
......
...@@ -823,7 +823,10 @@ package Sinfo is ...@@ -823,7 +823,10 @@ package Sinfo is
-- See also the description of Do_Range_Check for this case. The only -- See also the description of Do_Range_Check for this case. The only
-- attribute references which use this flag are Pred and Succ, where it -- attribute references which use this flag are Pred and Succ, where it
-- means that the result should be checked for going outside the base -- means that the result should be checked for going outside the base
-- range. Note that this flag is not set for modular types. -- range. Note that this flag is not set for modular types. This flag is
-- also set on conditional expression nodes if we are operating in either
-- MINIMIZED or ELIMINATED overflow checking mode (to make sure that we
-- properly process overflow checking for dependent expressions).
-- Do_Range_Check (Flag9-Sem) -- Do_Range_Check (Flag9-Sem)
-- This flag is set on an expression which appears in a context where a -- This flag is set on an expression which appears in a context where a
...@@ -3859,18 +3862,91 @@ package Sinfo is ...@@ -3859,18 +3862,91 @@ package Sinfo is
-- Note on overflow handling: When the overflow checking mode is set to -- Note on overflow handling: When the overflow checking mode is set to
-- MINIMIZED or ELIMINATED, nodes for signed arithmetic operations may -- MINIMIZED or ELIMINATED, nodes for signed arithmetic operations may
-- be modified to use a larger type for the operands and result. In -- be modified to use a larger type for the operands and result. In
-- these cases, the back end does not need the Entity field anyway, so -- the case where the computed range exceeds that of Long_Long_Integer,
-- there is no point in setting it. In fact we reuse the Entity field to -- and we are running in ELIMINATED mode, the operator node will be
-- record the possible range of the result. Entity points to an N_Range -- changed to be a call to the appropriate routine in System.Bignums.
-- node whose Low_Bound and High_Bound fields point to integer literal
-- nodes containing the computed bounds. These range nodes are only set ------------------------------------
-- for intermediate nodes whose parents are themselves either arithmetic -- 4.5.7 Conditional Expressions --
-- operators, or comparison or membership tests. The computed ranges are ------------------------------------
-- then used in processing the parent operation. In the case where the
-- computed range exceeds that of Long_Long_Integer, and we are running -- CONDITIONAL_EXPRESSION ::= IF_EXPRESSION | CASE_EXPRESSION
-- in ELIMINATED mode, the operator node will be changed to be a call to
-- the appropriate routine in System.Bignums, and in this case we forget --------------------------
-- about keeping track of the range. -- 4.5.7 If Expression --
----------------------------
-- IF_EXPRESSION ::=
-- if CONDITION then DEPENDENT_EXPRESSION
-- {elsif CONDITION then DEPENDENT_EXPRESSION}
-- [else DEPENDENT_EXPRESSION]
-- DEPENDENT_EXPRESSION ::= EXPRESSION
-- Note: if we have (IF x1 THEN x2 ELSIF x3 THEN x4 ELSE x5) then it
-- is represented as (IF x1 THEN x2 ELSE (IF x3 THEN x4 ELSE x5)) and
-- the Is_Elsif flag is set on the inner conditional expression.
-- Note: to be consistent with the grammar, the following node should
-- really be named N_If_Expression, but historically it was always
-- N_Conditional_Expression, so it would be a bit of an earthquake
-- to change, and actually conditional expression seems a bit clearer
-- than if expression in typical contexts, so we decide to leave it!
-- N_Conditional_Expression
-- Sloc points to IF or ELSIF keyword
-- Expressions (List1)
-- Then_Actions (List2-Sem)
-- Else_Actions (List3-Sem)
-- Is_Elsif (Flag13) (set if comes from ELSIF)
-- Do_Overflow_Check (Flag17-Sem)
-- plus fields for expression
-- Expressions here is a three-element list, whose first element is the
-- condition, the second element is the dependent expression after THEN
-- and the third element is the dependent expression after the ELSE
-- (explicitly set to True if missing).
-- Note: the Then_Actions and Else_Actions fields are always set to
-- No_List in the tree passed to Gigi. These fields are used only
-- for temporary processing purposes in the expander.
----------------------------
-- 4.5.7 Case Expression --
----------------------------
-- CASE_EXPRESSION ::=
-- case SELECTING_EXPRESSION is
-- CASE_EXPRESSION_ALTERNATIVE
-- {CASE_EXPRESSION_ALTERNATIVE}
-- Note that the Alternatives cannot include pragmas (this contrasts
-- with the situation of case statements where pragmas are allowed).
-- N_Case_Expression
-- Sloc points to CASE
-- Expression (Node3) (the selecting expression)
-- Alternatives (List4) (the case expression alternatives)
-- Do_Overflow_Check (Flag17-Sem)
----------------------------------------
-- 4.5.7 Case Expression Alternative --
----------------------------------------
-- CASE_EXPRESSION_ALTERNATIVE ::=
-- when DISCRETE_CHOICE_LIST =>
-- DEPENDENT_EXPRESSION
-- N_Case_Expression_Alternative
-- Sloc points to WHEN
-- Actions (List1)
-- Discrete_Choices (List4)
-- Expression (Node3)
-- Note: The Actions field temporarily holds any actions associated with
-- evaluation of the Expression. During expansion of the case expression
-- these actions are wrapped into an N_Expressions_With_Actions node
-- replacing the original expression.
--------------------------------- ---------------------------------
-- 4.5.9 Quantified Expression -- -- 4.5.9 Quantified Expression --
...@@ -6877,86 +6953,9 @@ package Sinfo is ...@@ -6877,86 +6953,9 @@ package Sinfo is
-- show this syntax. -- show this syntax.
-- Note: Case_Expression and Conditional_Expression is in this section for -- Note: Case_Expression and Conditional_Expression is in this section for
-- now, since they are extensions. We will move them to their appropriate -- historical reasons, since they were initially extensions. Now that they
-- places when they are officially approved as extensions (and then we will -- are an official part of Ada 2012, we should move them to the appropriate
-- know what the exact grammar and place in the Reference Manual is!) -- section of this package. ???
---------------------
-- Case Expression --
---------------------
-- CASE_EXPRESSION ::=
-- case EXPRESSION is
-- CASE_EXPRESSION_ALTERNATIVE
-- {CASE_EXPRESSION_ALTERNATIVE}
-- Note that the Alternatives cannot include pragmas (this contrasts
-- with the situation of case statements where pragmas are allowed).
-- N_Case_Expression
-- Sloc points to CASE
-- Expression (Node3)
-- Alternatives (List4)
---------------------------------
-- Case Expression Alternative --
---------------------------------
-- CASE_STATEMENT_ALTERNATIVE ::=
-- when DISCRETE_CHOICE_LIST =>
-- EXPRESSION
-- N_Case_Expression_Alternative
-- Sloc points to WHEN
-- Actions (List1)
-- Discrete_Choices (List4)
-- Expression (Node3)
-- Note: The Actions field temporarily holds any actions associated with
-- evaluation of the Expression. During expansion of the case expression
-- these actions are wrapped into an N_Expressions_With_Actions node
-- replacing the original expression.
----------------------------
-- Conditional Expression --
----------------------------
-- This node is used to represent an expression corresponding to the
-- C construct (condition ? then-expression : else_expression), where
-- Expressions is a three element list, whose first expression is the
-- condition, and whose second and third expressions are the then and
-- else expressions respectively.
-- Note: the Then_Actions and Else_Actions fields are always set to
-- No_List in the tree passed to Gigi. These fields are used only
-- for temporary processing purposes in the expander.
-- The Ada language does not permit conditional expressions, however
-- this is under discussion as a possible extension by the ARG, and we
-- have implemented a form of this capability in GNAT under control of
-- the -gnatX switch. The syntax is:
-- CONDITIONAL_EXPRESSION ::=
-- if EXPRESSION then EXPRESSION
-- {elsif EXPRESSION then EXPRESSION}
-- [else EXPRESSION]
-- And we add the additional constructs
-- PRIMARY ::= ( CONDITIONAL_EXPRESSION )
-- PRAGMA_ARGUMENT_ASSOCIATION ::= CONDITIONAL_EXPRESSION
-- Note: if we have (IF x1 THEN x2 ELSIF x3 THEN x4 ELSE x5) then it
-- is represented as (IF x1 THEN x2 ELSE (IF x3 THEN x4 ELSE x5)) and
-- the Is_Elsif flag is set on the inner conditional expression.
-- N_Conditional_Expression
-- Sloc points to IF or ELSIF keyword
-- Expressions (List1)
-- Then_Actions (List2-Sem)
-- Else_Actions (List3-Sem)
-- Is_Elsif (Flag13) (set if comes from ELSIF)
-- plus fields for expression
-------------- --------------
-- Contract -- -- Contract --
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment