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
This commit is contained in:
Robert Dewar 2012-10-02 08:37:54 +00:00 committed by Arnaud Charlet
parent 2492305bcc
commit 4b1c4f20d8
8 changed files with 400 additions and 136 deletions

View File

@ -1,3 +1,22 @@
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>
* exp_ch4.adb (Expand_N_Case_Expression): Do not introduce

View File

@ -193,15 +193,17 @@ package body Checks is
-- Local Subprograms --
-----------------------
procedure Apply_Arithmetic_Overflow_Normal (N : Node_Id);
procedure Apply_Arithmetic_Overflow_Checked_Suppressed (N : Node_Id);
-- Used to apply arithmetic overflow checks for all cases except operators
-- on signed arithmetic types in Minimized/Eliminate case (for which we
-- call Apply_Arithmetic_Overflow_Minimized_Eliminated below).
-- call Apply_Arithmetic_Overflow_Minimized_Eliminated below). N is always
-- a signed integer arithmetic operator (conditional expression excluded).
procedure Apply_Arithmetic_Overflow_Minimized_Eliminated (Op : Node_Id);
-- Used to apply arithmetic overflow checks for the case where the overflow
-- checking mode is Minimized or Eliminated (and the Do_Overflow_Check flag
-- is known to be set) and we have an signed integer arithmetic op.
-- is known to be set) and we have an signed integer arithmetic op (which
-- includes the case of conditional expressions).
procedure Apply_Division_Check
(N : Node_Id;
@ -311,8 +313,10 @@ package body Checks is
function Is_Signed_Integer_Arithmetic_Op (N : Node_Id) return Boolean;
-- Returns True if node N is for an arithmetic operation with signed
-- integer operands. This is the kind of node for which special handling
-- applies in MINIMIZED or EXTENDED overflow checking mode.
-- integer operands. This includes unary and binary operators, and also
-- if and case expression nodes where the dependent expressions are of
-- a signed integer type. These are the kinds of nodes for which special
-- handling applies in MINIMIZED or EXTENDED overflow checking mode.
function Range_Or_Validity_Checks_Suppressed
(Expr : Node_Id) return Boolean;
@ -767,7 +771,7 @@ package body Checks is
or else not Do_Overflow_Check (N)
or else not Is_Signed_Integer_Arithmetic_Op (N)
then
Apply_Arithmetic_Overflow_Normal (N);
Apply_Arithmetic_Overflow_Checked_Suppressed (N);
-- Otherwise use the new routine for Minimized/Eliminated modes for
-- the case of a signed integer arithmetic op, with Do_Overflow_Check
@ -778,9 +782,9 @@ package body Checks is
end if;
end Apply_Arithmetic_Overflow_Check;
--------------------------------------
-- Apply_Arithmetic_Overflow_Normal --
--------------------------------------
--------------------------------------------------
-- Apply_Arithmetic_Overflow_Checked_Suppressed --
--------------------------------------------------
-- This routine is called only if the type is an integer type, and a
-- software arithmetic overflow check may be needed for op (add, subtract,
@ -798,7 +802,7 @@ package body Checks is
-- Note: we also call this routine if we decide in the MINIMIZED case
-- to give up and just generate an overflow check without any fuss.
procedure Apply_Arithmetic_Overflow_Normal (N : Node_Id) is
procedure Apply_Arithmetic_Overflow_Checked_Suppressed (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
Typ : constant Entity_Id := Etype (N);
Rtyp : constant Entity_Id := Root_Type (Typ);
@ -1061,7 +1065,7 @@ package body Checks is
when RE_Not_Available =>
return;
end;
end Apply_Arithmetic_Overflow_Normal;
end Apply_Arithmetic_Overflow_Checked_Suppressed;
----------------------------------------------------
-- Apply_Arithmetic_Overflow_Minimized_Eliminated --
@ -1081,7 +1085,7 @@ package body Checks is
-- Original result type
Check_Mode : constant Overflow_Check_Type :=
Overflow_Check_Mode (Etype (Op));
Overflow_Check_Mode (Etype (Op));
pragma Assert (Check_Mode in Minimized_Or_Eliminated);
Lo, Hi : Uint;
@ -1090,7 +1094,7 @@ package body Checks is
begin
-- Nothing to do if our parent is one of the following:
-- Another signed integer arithmetic operation
-- Another signed integer arithmetic op
-- A membership operation
-- A comparison operation
@ -1111,7 +1115,7 @@ package body Checks is
return;
end if;
-- Otherwise, we have a top level arithmetic operator node, and this
-- Otherwise, we have a top level arithmetic operation node, and this
-- is where we commence the special processing for minimize/eliminate.
-- This is the case where we tell the machinery not to move into Bignum
-- mode at this top level (of course the top level operation will still
@ -3799,7 +3803,7 @@ package body Checks is
Loc : constant Source_Ptr := Sloc (N);
begin
-- Nothing to do if Bignum already
-- Nothing to do if Bignum already except call Relocate_Node
if Is_RTE (Etype (N), RE_Bignum) then
return Relocate_Node (N);
@ -6254,6 +6258,13 @@ package body Checks is
N_Op_Rem | N_Op_Subtract =>
return Is_Signed_Integer_Type (Etype (N));
when N_Conditional_Expression |
N_Case_Expression =>
return Is_Signed_Integer_Type (Etype (N));
when N_Case_Expression_Alternative =>
return Is_Signed_Integer_Type (Etype (Parent (N)));
when others =>
return False;
end case;
@ -6677,7 +6688,9 @@ package body Checks is
Hi : out Uint;
Top_Level : Boolean)
is
pragma Assert (Is_Signed_Integer_Type (Etype (N)));
Rtyp : constant Entity_Id := Etype (N);
pragma Assert (Is_Signed_Integer_Type (Rtyp));
-- Result type, must be a signed integer type
Check_Mode : constant Overflow_Check_Type := Overflow_Check_Mode (Empty);
pragma Assert (Check_Mode in Minimized_Or_Eliminated);
@ -6685,15 +6698,16 @@ package body Checks is
Loc : constant Source_Ptr := Sloc (N);
Rlo, Rhi : Uint;
-- Ranges of values for right operand
-- Ranges of values for right operand (operator case)
Llo, Lhi : Uint;
-- Ranges of values for left operand
-- Ranges of values for left operand (operator case)
LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
-- Operands and results are of this type when we convert
LLLo, LLHi : Uint;
LLLo : constant Uint := Intval (Type_Low_Bound (LLIB));
LLHi : constant Uint := Intval (Type_High_Bound (LLIB));
-- Bounds of Long_Long_Integer
Binary : constant Boolean := Nkind (N) in N_Binary_Op;
@ -6705,7 +6719,17 @@ package body Checks is
Bignum_Operands : Boolean;
-- Set True if one or more operands is already of type Bignum, meaning
-- that for sure (regardless of Top_Level setting) we are committed to
-- doing the operation in Bignum mode.
-- doing the operation in Bignum mode (or in the case of a case or if
-- expression, converting all the dependent expressions to bignum).
Long_Long_Integer_Operands : Boolean;
-- Set True if one r more operands is already of type Long_Loong_Integer
-- which means that if the result is known to be in the result type
-- range, then we must convert such operands back to the result type.
-- This switch is properly set only when Bignum_Operands is False.
function In_Result_Range return Boolean;
-- Returns True iff Lo .. Hi are within range of the result type
procedure Max (A : in out Uint; B : Uint);
-- If A is No_Uint, sets A to B, else to UI_Max (A, B);
@ -6713,6 +6737,23 @@ package body Checks is
procedure Min (A : in out Uint; B : Uint);
-- If A is No_Uint, sets A to B, else to UI_Min (A, B);
---------------------
-- In_Result_Range --
---------------------
function In_Result_Range return Boolean is
begin
if Is_Static_Subtype (Etype (N)) then
return Lo >= Expr_Value (Type_Low_Bound (Rtyp))
and then
Hi <= Expr_Value (Type_High_Bound (Rtyp));
else
return Lo >= Expr_Value (Type_Low_Bound (Base_Type (Rtyp)))
and then
Hi <= Expr_Value (Type_High_Bound (Base_Type (Rtyp)));
end if;
end In_Result_Range;
---------
-- Max --
---------
@ -6738,7 +6779,7 @@ package body Checks is
-- Start of processing for Minimize_Eliminate_Overflow_Checks
begin
-- Case where we do not have an arithmetic operator
-- Case where we do not have a signed integer arithmetic operation
if not Is_Signed_Integer_Arithmetic_Op (N) then
@ -6762,18 +6803,168 @@ package body Checks is
return;
-- If we have an arithmetic oeprator we make recursive calls on the
-- Processing for if expression
elsif Nkind (N) = N_Conditional_Expression then
declare
Then_DE : constant Node_Id := Next (First (Expressions (N)));
Else_DE : constant Node_Id := Next (Then_DE);
begin
Bignum_Operands := False;
Minimize_Eliminate_Overflow_Checks
(Then_DE, Lo, Hi, Top_Level => False);
if Lo = No_Uint then
Bignum_Operands := True;
end if;
Minimize_Eliminate_Overflow_Checks
(Else_DE, Rlo, Rhi, Top_Level => False);
if Rlo = No_Uint then
Bignum_Operands := True;
else
Long_Long_Integer_Operands :=
Etype (Then_DE) = LLIB or else Etype (Else_DE) = LLIB;
Min (Lo, Rlo);
Max (Hi, Rhi);
end if;
-- If at least one of our operands is now bignum, we must rebuild
-- the if expression to use bignum operands. We will analyze the
-- rebuilt if expression with overflow checks off, since once we
-- are in bignum mode, we are all done with overflow checks!
if Bignum_Operands then
Rewrite (N,
Make_Conditional_Expression (Loc,
Expressions => New_List (
Remove_Head (Expressions (N)),
Convert_To_Bignum (Then_DE),
Convert_To_Bignum (Else_DE)),
Is_Elsif => Is_Elsif (N)));
Analyze_And_Resolve
(N, RTE (RE_Bignum), Suppress => Overflow_Check);
-- 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).
elsif not Long_Long_Integer_Operands then
Set_Do_Overflow_Check (N, False);
-- Otherwise convert us to long long integer mode. Note that we
-- don't need any further overflow checking at this level.
else
Convert_To_And_Rewrite (LLIB, Then_DE);
Convert_To_And_Rewrite (LLIB, Else_DE);
Set_Etype (N, LLIB);
Set_Do_Overflow_Check (N, False);
end if;
end;
return;
-- Here for case expression
elsif Nkind (N) = N_Case_Expression then
Bignum_Operands := False;
Long_Long_Integer_Operands := False;
Lo := No_Uint;
Hi := No_Uint;
declare
Alt : Node_Id;
New_Alts : List_Id;
New_Exp : Node_Id;
Rtype : Entity_Id;
begin
-- Loop through expressions applying recursive call
Alt := First (Alternatives (N));
while Present (Alt) loop
declare
Aexp : constant Node_Id := Expression (Alt);
begin
Minimize_Eliminate_Overflow_Checks
(Aexp, Lo, Hi, Top_Level => False);
if Lo = No_Uint then
Bignum_Operands := True;
elsif Etype (Aexp) = LLIB then
Long_Long_Integer_Operands := True;
end if;
end;
Next (Alt);
end loop;
-- If we have no bignum or long long integer operands, it means
-- 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.
if not (Bignum_Operands or else Long_Long_Integer_Operands) then
Set_Do_Overflow_Check (N, False);
Set_Analyzed (N, False);
-- Otherwise we are going to rebuild the case expression using
-- either bignum or long long integer operands throughout.
else
New_Alts := New_List;
Alt := First (Alternatives (N));
while Present (Alt) loop
if Bignum_Operands then
New_Exp := Convert_To_Bignum (Expression (Alt));
Rtype := RTE (RE_Bignum);
else
New_Exp := Convert_To (LLIB, Expression (Alt));
Rtype := LLIB;
end if;
Append_To (New_Alts,
Make_Case_Expression_Alternative (Sloc (Alt),
Actions => No_List,
Discrete_Choices => Discrete_Choices (Alt),
Expression => New_Exp));
Next (Alt);
end loop;
Rewrite (N,
Make_Case_Expression (Loc,
Expression => Expression (N),
Alternatives => New_Alts));
Analyze_And_Resolve (N, Rtype, Suppress => Overflow_Check);
end if;
end;
return;
end if;
-- If we have an arithmetic operator we make recursive calls on the
-- operands to get the ranges (and to properly process the subtree
-- that lies below us!)
else
Minimize_Eliminate_Overflow_Checks
(Right_Opnd (N), Rlo, Rhi, Top_Level => False);
Minimize_Eliminate_Overflow_Checks
(Right_Opnd (N), Rlo, Rhi, Top_Level => False);
if Binary then
Minimize_Eliminate_Overflow_Checks
(Left_Opnd (N), Llo, Lhi, Top_Level => False);
end if;
if Binary then
Minimize_Eliminate_Overflow_Checks
(Left_Opnd (N), Llo, Lhi, Top_Level => False);
end if;
-- If either operand is a bignum, then result will be a bignum
@ -6788,6 +6979,10 @@ package body Checks is
else
Bignum_Operands := False;
Long_Long_Integer_Operands :=
Etype (Right_Opnd (N)) = LLIB
or else (Binary and then Etype (Left_Opnd (N)) = LLIB);
case Nkind (N) is
-- Absolute value
@ -7136,9 +7331,6 @@ package body Checks is
-- 0 .. 1, but the cases are rare and it is not worth the effort.
-- Failing to do this switching back is only an efficiency issue.
LLLo := Intval (Type_Low_Bound (LLIB));
LLHi := Intval (Type_High_Bound (LLIB));
if Lo = No_Uint or else Lo < LLLo or else Hi > LLHi then
-- OK, we are definitely outside the range of Long_Long_Integer. The
@ -7248,6 +7440,14 @@ package body Checks is
Set_Do_Overflow_Check (N, False);
end if;
-- If Result is in range of the result type, and we don't have any
-- Long_Long_Integer operands, then overflow checking is not needed
-- and we have nothing to do (we have already reset Do_Overflow_Check).
if In_Result_Range and not Long_Long_Integer_Operands then
return;
end if;
-- Here we will do the operation in Long_Long_Integer. We do this even
-- if we know an overflow check is required, better to do this in long
-- long integer mode, since we are less likely to overflow!

View File

@ -135,13 +135,14 @@ package Checks is
-- larger than the overlaid object.
procedure Apply_Arithmetic_Overflow_Check (N : Node_Id);
-- Given a binary arithmetic operator (+ - *) expand a software integer
-- overflow check using range checks on a larger checking type or a call
-- to an appropriate runtime routine. This is used for all three operators
-- for the signed integer case, and for +/- in the fixed-point case. The
-- check is expanded only if Software_Overflow_Checking is enabled and
-- Do_Overflow_Check is set on node N. Note that divide is handled
-- separately using Apply_Arithmetic_Divide_Overflow_Check.
-- Handle overflow checking for an arithmetic operator. Also handles the
-- cases of ELIMINATED and MINIMIZED overflow checking mode. If the mode
-- is one of the latter two, then this routine can also be called with
-- a conditional expression node to make sure that we properly handle
-- overflow checking for dependent expressions. This routine handles
-- front end vs back end overflow checks (in the front end case it expands
-- the necessary check). Note that divide is handled separately using
-- Apply_Arithmetic_Divide_Overflow_Check.
procedure Apply_Constraint_Check
(N : Node_Id;

View File

@ -4776,6 +4776,18 @@ package body Exp_Ch4 is
Fexp : Node_Id;
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
-- case X is when A => AX, when B => BX ...
@ -5204,6 +5216,15 @@ package body Exp_Ch4 is
-- the same approach as a C conditional expression.
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;
end if;

View File

@ -104,8 +104,7 @@ package body System.Bignums is
function Normalize
(X : Digit_Vector;
Neg : Boolean := False) return Bignum
with Pre => X'First = 1;
Neg : Boolean := False) return Bignum;
-- 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
-- result is zero, the sign is forced positive.

View File

@ -5941,6 +5941,16 @@ package body Sem_Res is
Set_Etype (N, Typ);
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;
-------------------------------
@ -6134,8 +6144,9 @@ package body Sem_Res is
Resolve (Then_Expr, Typ);
Then_Typ := Etype (Then_Expr);
-- When the "then" and "else" expressions are of a scalar type, insert
-- a conversion to ensure the generation of a constraint check.
-- When the "then" expression is of a scalar type different from the
-- result type, then insert a conversion to ensure the generation of
-- a constraint check.
if Is_Scalar_Type (Then_Typ)
and then Then_Typ /= Typ
@ -6174,6 +6185,16 @@ package body Sem_Res is
Set_Etype (N, Typ);
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;
-----------------------------------------

View File

@ -927,6 +927,8 @@ package body Sinfo is
pragma Assert (False
or else NT (N).Nkind in N_Op
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);
return Flag17 (N);
end Do_Overflow_Check;
@ -3998,6 +4000,8 @@ package body Sinfo is
pragma Assert (False
or else NT (N).Nkind in N_Op
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);
Set_Flag17 (N, Val);
end Set_Do_Overflow_Check;

View File

@ -823,7 +823,10 @@ package Sinfo is
-- 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
-- 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)
-- This flag is set on an expression which appears in a context where a
@ -3859,18 +3862,91 @@ package Sinfo is
-- Note on overflow handling: When the overflow checking mode is set to
-- MINIMIZED or ELIMINATED, nodes for signed arithmetic operations may
-- 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
-- there is no point in setting it. In fact we reuse the Entity field to
-- record the possible range of the result. Entity points to an N_Range
-- 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
-- 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
-- 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.
-- the case where the computed range exceeds that of Long_Long_Integer,
-- and we are running in ELIMINATED mode, the operator node will be
-- changed to be a call to the appropriate routine in System.Bignums.
------------------------------------
-- 4.5.7 Conditional Expressions --
------------------------------------
-- CONDITIONAL_EXPRESSION ::= IF_EXPRESSION | CASE_EXPRESSION
--------------------------
-- 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 --
@ -6877,86 +6953,9 @@ package Sinfo is
-- show this syntax.
-- Note: Case_Expression and Conditional_Expression is in this section for
-- now, since they are extensions. We will move them to their appropriate
-- places when they are officially approved as extensions (and then we will
-- know what the exact grammar and place in the Reference Manual is!)
---------------------
-- 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
-- historical reasons, since they were initially extensions. Now that they
-- are an official part of Ada 2012, we should move them to the appropriate
-- section of this package. ???
--------------
-- Contract --