From: Piotr Trojanek <trojanek@adacore.com>
Fix computation of attribute 'Width for enumeration types with
Discard_Name aspect enabled.
gcc/ada/
* exp_imgv.adb (Expand_Width_Attribute): Fix for 'Width that
is computed at run time.
* sem_attr.adb (Eval_Attribute): Fix for 'Width that is computed
at compilation time.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/exp_imgv.adb | 25 +++++++++++++++----------
gcc/ada/sem_attr.adb | 7 ++++---
2 files changed, 19 insertions(+), 13 deletions(-)
@@ -2294,7 +2294,7 @@ package body Exp_Imgv is
-- in the range of the subtype + 1 for the space at the start. We
-- build:
- -- Tnn : constant Integer := Rtyp'Pos (Ptyp'Last)
+ -- Tnn : constant Integer := Rtyp'Pos (Ptyp'Last);
-- and replace the expression by
@@ -2320,9 +2320,15 @@ package body Exp_Imgv is
declare
Tnn : constant Entity_Id := Make_Temporary (Loc, 'T');
Cexpr : Node_Id;
- P : Int;
- M : Int;
- K : Int;
+
+ P : constant Nat :=
+ UI_To_Int (Enumeration_Pos (Entity (Type_High_Bound (Rtyp))));
+ -- The largest value that might need to be represented
+
+ K : Pos;
+ M : Pos;
+ -- K is the number of chars that will fit the image of 0..M-1;
+ -- M is the smallest number that won't fit in K chars.
begin
Insert_Action (N,
@@ -2342,14 +2348,13 @@ package body Exp_Imgv is
Attribute_Name => Name_Last))))));
-- OK, now we need to build the if expression. First get the
- -- value of M, the largest possible value needed.
+ -- values of K and M for the largest possible value P.
- P := UI_To_Int
- (Enumeration_Pos (Entity (Type_High_Bound (Rtyp))));
+ K := 2;
+ M := 10;
+ -- With 2 characters we can represent values in 0..9
- K := 1;
- M := 1;
- while M < P loop
+ while P >= M loop
M := M * 10;
K := K + 1;
end loop;
@@ -10906,9 +10906,10 @@ package body Sem_Attr is
-- that accommodates the Pos of the largest value, which
-- is the high bound of the range + one for the space.
- W := 1;
- T := Hi;
- while T /= 0 loop
+ W := 1; -- one character for the leading space
+ W := W + 1; -- one character for the 0 .. 9 digit
+ T := Hi; -- one character for every decimal digit
+ while T >= 10 loop
T := T / 10;
W := W + 1;
end loop;