aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/exp_attr.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/exp_attr.adb')
-rw-r--r--gcc/ada/exp_attr.adb38
1 files changed, 20 insertions, 18 deletions
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index b21592c..ff3d54f 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -6196,20 +6196,19 @@ package body Exp_Attr is
-- Round --
-----------
- -- The handling of the Round attribute is quite delicate. The processing
- -- in Sem_Attr introduced a conversion to universal real, reflecting the
- -- semantics of Round, but we do not want anything to do with universal
- -- real at runtime, since this corresponds to using floating-point
- -- arithmetic.
+ -- The handling of the Round attribute is delicate when the operand is
+ -- universal fixed. In this case, the processing in Sem_Attr introduced
+ -- a conversion to universal real, reflecting the semantics of Round,
+ -- but we do not want anything to do with universal real at run time,
+ -- since this corresponds to using floating-point arithmetic.
-- What we have now is that the Etype of the Round attribute correctly
-- indicates the final result type. The operand of the Round is the
-- conversion to universal real, described above, and the operand of
-- this conversion is the actual operand of Round, which may be the
- -- special case of a fixed point multiplication or division (Etype =
- -- universal fixed)
+ -- special case of a fixed point multiplication or division.
- -- The exapander will expand first the operand of the conversion, then
+ -- The expander will expand first the operand of the conversion, then
-- the conversion, and finally the round attribute itself, since we
-- always work inside out. But we cannot simply process naively in this
-- order. In the semantic world where universal fixed and real really
@@ -6217,14 +6216,13 @@ package body Exp_Attr is
-- implementation world, where universal real is a floating-point type,
-- we would get the wrong result.
- -- So the approach is as follows. First, when expanding a multiply or
- -- divide whose type is universal fixed, we do nothing at all, instead
- -- deferring the operation till later.
-
- -- The actual processing is done in Expand_N_Type_Conversion which
- -- handles the special case of Round by looking at its parent to see if
- -- it is a Round attribute, and if it is, handling the conversion (or
- -- its fixed multiply/divide child) in an appropriate manner.
+ -- So the approach is as follows. When expanding a multiply or divide
+ -- whose type is universal fixed, Fixup_Universal_Fixed_Operation will
+ -- look up and skip the conversion to universal real if its parent is
+ -- a Round attribute, taking information from this attribute node. In
+ -- the other cases, Expand_N_Type_Conversion does the same by looking
+ -- at its parent to see if it is a Round attribute, before calling the
+ -- fixed-point expansion routine.
-- This means that by the time we get to expanding the Round attribute
-- itself, the Round is nothing more than a type conversion (and will
@@ -6232,8 +6230,12 @@ package body Exp_Attr is
-- appropriate conversion operation.
when Attribute_Round =>
- Rewrite (N,
- Convert_To (Etype (N), Relocate_Node (First (Exprs))));
+ if Etype (First (Exprs)) = Etype (N) then
+ Rewrite (N, Relocate_Node (First (Exprs)));
+ else
+ Rewrite (N, Convert_To (Etype (N), First (Exprs)));
+ Set_Rounded_Result (N);
+ end if;
Analyze_And_Resolve (N);
--------------