Commit 8113b0c7 by Eric Botcazou Committed by Pierre-Marie de Rodat

[Ada] Overhaul code implementing conversions involving fixed-point types

This ovehauls the code implementing conversions involving fixed-point
types in the front-end because it leaks the Do_Range_Check flag in
several places to the back-end, which is a violation of the documented
interface between front-end and back-end.

This also does a bit of housekeeping work throughout it in the process.

There should be essentially no functional changes.

2019-07-22  Eric Botcazou  <ebotcazou@adacore.com>

gcc/ada/

	* checks.adb (Apply_Type_Conversion_Checks): Do not set
	Do_Range_Check flag on conversions from fixed-point types
	either.
	* exp_attr.adb: Add use and with clause for Expander.
	(Expand_N_Attribute_Reference) <Fixed_Value, Integer_Value>: Set
	the Conversion_OK flag and do not generate overflow/range checks
	manually.
	* exp_ch4.adb (Expand_N_Qualified_Expression): Remove
	superfluous clearing of Do_Range_Check flag.
	(Discrete_Range_Check): New procedure to generate a range check
	for discrete types.
	(Real_Range_Check): Remove redundant local variable and adjust.
	Remove useless shortcut.  Clear Do_Range_Check flag on all
	paths.
	(Expand_N_Type_Conversion): Remove redundant test on
	Conversion_OK.  Call Discrete_Range_Check to generate range
	checks on discrete types.  Remove obsolete code for
	float-to-integer conversions.  Add code to generate range checks
	for conversions involving fixed-point types.

From-SVN: r273692
parent c936411f
2019-07-22 Eric Botcazou <ebotcazou@adacore.com> 2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
* checks.adb (Apply_Type_Conversion_Checks): Do not set
Do_Range_Check flag on conversions from fixed-point types
either.
* exp_attr.adb: Add use and with clause for Expander.
(Expand_N_Attribute_Reference) <Fixed_Value, Integer_Value>: Set
the Conversion_OK flag and do not generate overflow/range checks
manually.
* exp_ch4.adb (Expand_N_Qualified_Expression): Remove
superfluous clearing of Do_Range_Check flag.
(Discrete_Range_Check): New procedure to generate a range check
for discrete types.
(Real_Range_Check): Remove redundant local variable and adjust.
Remove useless shortcut. Clear Do_Range_Check flag on all
paths.
(Expand_N_Type_Conversion): Remove redundant test on
Conversion_OK. Call Discrete_Range_Check to generate range
checks on discrete types. Remove obsolete code for
float-to-integer conversions. Add code to generate range checks
for conversions involving fixed-point types.
2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
* sprint.ads: Fix pasto in comment. * sprint.ads: Fix pasto in comment.
2019-07-22 Javier Miranda <miranda@adacore.com> 2019-07-22 Javier Miranda <miranda@adacore.com>
......
...@@ -3622,13 +3622,14 @@ package body Checks is ...@@ -3622,13 +3622,14 @@ package body Checks is
-- will not be generated. -- will not be generated.
if GNATprove_Mode if GNATprove_Mode
or else not Is_Fixed_Point_Type (Expr_Type) or else (not Is_Fixed_Point_Type (Expr_Type)
and then not Is_Fixed_Point_Type (Target_Type))
then then
Apply_Scalar_Range_Check Apply_Scalar_Range_Check
(Expr, Target_Type, Fixed_Int => Conv_OK); (Expr, Target_Type, Fixed_Int => Conv_OK);
else else
Set_Do_Range_Check (Expression (N), False); Set_Do_Range_Check (Expr, False);
end if; end if;
-- If the target type has predicates, we need to indicate -- If the target type has predicates, we need to indicate
......
...@@ -39,6 +39,7 @@ with Exp_Pakd; use Exp_Pakd; ...@@ -39,6 +39,7 @@ with Exp_Pakd; use Exp_Pakd;
with Exp_Strm; use Exp_Strm; with Exp_Strm; use Exp_Strm;
with Exp_Tss; use Exp_Tss; with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util; with Exp_Util; use Exp_Util;
with Expander; use Expander;
with Freeze; use Freeze; with Freeze; use Freeze;
with Gnatvsn; use Gnatvsn; with Gnatvsn; use Gnatvsn;
with Itypes; use Itypes; with Itypes; use Itypes;
...@@ -3540,7 +3541,7 @@ package body Exp_Attr is ...@@ -3540,7 +3541,7 @@ package body Exp_Attr is
-- We transform -- We transform
-- fixtype'Fixed_Value (integer-value) -- fixtype'Fixed_Value (integer-value)
-- inttype'Fixed_Value (fixed-value) -- inttype'Integer_Value (fixed-value)
-- into -- into
...@@ -3549,75 +3550,30 @@ package body Exp_Attr is ...@@ -3549,75 +3550,30 @@ package body Exp_Attr is
-- respectively. -- respectively.
-- We do all the required analysis of the conversion here, because we do -- We set Conversion_OK on the conversion because we do not want it
-- not want this to go through the fixed-point conversion circuits. Note -- to go through the fixed-point conversion circuits.
-- that the back end always treats fixed-point as equivalent to the
-- corresponding integer type anyway.
-- However, in order to remove the handling of Do_Range_Check from the
-- backend, we force the generation of a check on the result by
-- setting the result type appropriately. Apply_Conversion_Checks
-- will generate the required expansion.
when Attribute_Fixed_Value when Attribute_Fixed_Value
| Attribute_Integer_Value | Attribute_Integer_Value
=> =>
Rewrite (N, Rewrite (N, OK_Convert_To (Entity (Pref), First (Exprs)));
Make_Type_Conversion (Loc,
Subtype_Mark => New_Occurrence_Of (Entity (Pref), Loc),
Expression => Relocate_Node (First (Exprs))));
-- Indicate that the result of the conversion may require a -- Note that it might appear that a properly analyzed unchecked
-- range check (see below);
Set_Etype (N, Base_Type (Entity (Pref)));
Set_Analyzed (N);
-- Note: it might appear that a properly analyzed unchecked
-- conversion would be just fine here, but that's not the case, -- conversion would be just fine here, but that's not the case,
-- since the full range checks performed by the following code -- since the full range checks performed by the following calls
-- are critical. -- are critical.
-- Given that Fixed-point conversions are not further expanded
-- to prevent the involvement of real type operations we have to
-- construct two checks explicitly: one on the operand, and one
-- on the result. This used to be done in part in the back-end,
-- but for other targets (E.g. LLVM) it is preferable to create
-- the tests in full in the front-end.
if Is_Fixed_Point_Type (Etype (N)) then
declare
Loc : constant Source_Ptr := Sloc (N);
Equiv_T : constant Entity_Id := Make_Temporary (Loc, 'T', N);
Expr : constant Node_Id := Expression (N);
Fst : constant Entity_Id := Root_Type (Etype (N));
Decl : Node_Id;
begin Apply_Type_Conversion_Checks (N);
Decl :=
Make_Full_Type_Declaration (Sloc (N),
Defining_Identifier => Equiv_T,
Type_Definition =>
Make_Signed_Integer_Type_Definition (Loc,
Low_Bound =>
Make_Integer_Literal (Loc,
Intval =>
Corresponding_Integer_Value
(Type_Low_Bound (Fst))),
High_Bound =>
Make_Integer_Literal (Loc,
Intval =>
Corresponding_Integer_Value
(Type_High_Bound (Fst)))));
Insert_Action (N, Decl);
-- Verify that the conversion is possible
Generate_Range_Check (Expr, Equiv_T, CE_Overflow_Check_Failed); -- Note that Apply_Type_Conversion_Checks only deals with the
-- overflow checks on conversions involving fixed-point types
-- so we must apply range checks manually on them and expand.
-- and verify that the result is in range Apply_Scalar_Range_Check
(Expression (N), Etype (N), Fixed_Int => True);
Generate_Range_Check (N, Etype (N), CE_Range_Check_Failed); Set_Analyzed (N);
end; Expand (N);
end if;
----------- -----------
-- Floor -- -- Floor --
......
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