[COMMITTED,08/30] ada: Fix for attribute Width on enumeration types with Discard_Name

Message ID 20240520074858.222435-8-poulhies@adacore.com
State Committed
Commit fbe275e2458458ad517645d64619d3aac4467cf1
Headers
Series [COMMITTED,01/30] ada: Rework and augment documentation on strict aliasing |

Commit Message

Marc Poulhiès May 20, 2024, 7:48 a.m. UTC
  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(-)
  

Patch

diff --git a/gcc/ada/exp_imgv.adb b/gcc/ada/exp_imgv.adb
index 6dc59f2c6f3..e5d84cc52e3 100644
--- a/gcc/ada/exp_imgv.adb
+++ b/gcc/ada/exp_imgv.adb
@@ -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;
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index a921909685a..96f216cc587 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -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;