[COMMITTED] ada: Refactor code to remove GNATcheck violation

Message ID 20231019144202.339662-1-poulhies@adacore.com
State Accepted
Headers
Series [COMMITTED] ada: Refactor code to remove GNATcheck violation |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Marc Poulhiès Oct. 19, 2023, 2:42 p.m. UTC
  From: Sheri Bernstein <bernstein@adacore.com>

Rewrite for loop containing an exit (which violates GNATcheck
rule Exits_From_Conditional_Loops), to use a while loop
which contains the exit criteria in its condition.
Also, move special case of first time through loop, to come
before loop.

gcc/ada/

	* libgnat/s-imagef.adb (Set_Image_Fixed): Refactor loop.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/libgnat/s-imagef.adb | 75 +++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 35 deletions(-)
  

Patch

diff --git a/gcc/ada/libgnat/s-imagef.adb b/gcc/ada/libgnat/s-imagef.adb
index 3f6bfa20cb2..6194a3163de 100644
--- a/gcc/ada/libgnat/s-imagef.adb
+++ b/gcc/ada/libgnat/s-imagef.adb
@@ -307,6 +307,9 @@  package body System.Image_F is
       YY : Int := Y;
       --  First two operands of the scaled divide
 
+      J : Natural;
+      --  Loop index
+
    begin
       --  Set the first character like Image
 
@@ -317,59 +320,61 @@  package body System.Image_F is
          Ndigs := 0;
       end if;
 
-      for J in 1 .. N loop
-         exit when XX = 0;
+      --  First round of scaled divide
 
+      if XX /= 0 then
          Scaled_Divide (XX, YY, Z, Q, R => XX, Round => False);
+         if Q /= 0 then
+            Set_Image_Integer (Q, Digs, Ndigs);
+         end if;
 
-         if J = 1 then
-            if Q /= 0 then
-               Set_Image_Integer (Q, Digs, Ndigs);
-            end if;
-
-            Scale := Scale + D;
+         Scale := Scale + D;
 
-            --  Prepare for next round, if any
+         --  Prepare for next round, if any
 
-            YY := 10**Maxdigs;
+         YY := 10**Maxdigs;
+      end if;
 
-         else
-            pragma Assert (-10**Maxdigs < Q and then Q < 10**Maxdigs);
+      J := 2;
+      while J <= N and then XX /= 0 loop
+         Scaled_Divide (XX, YY, Z, Q, R => XX, Round => False);
 
-            Len := 0;
-            Set_Image_Integer (abs Q, Buf, Len);
+         pragma Assert (-10**Maxdigs < Q and then Q < 10**Maxdigs);
 
-            pragma Assert (1 <= Len and then Len <= Maxdigs);
+         Len := 0;
+         Set_Image_Integer (abs Q, Buf, Len);
 
-            --  If no character but the space has been written, write the
-            --  minus if need be, since Set_Image_Integer did not do it.
+         pragma Assert (1 <= Len and then Len <= Maxdigs);
 
-            if Ndigs <= 1 then
-               if Q /= 0 then
-                  if Ndigs = 0 then
-                     Digs (1) := '-';
-                  end if;
+         --  If no character but the space has been written, write the
+         --  minus if need be, since Set_Image_Integer did not do it.
 
-                  Digs (2 .. Len + 1) := Buf (1 .. Len);
-                  Ndigs := Len + 1;
+         if Ndigs <= 1 then
+            if Q /= 0 then
+               if Ndigs = 0 then
+                  Digs (1) := '-';
                end if;
 
-            --  Or else pad the output with zeroes up to Maxdigs
+               Digs (2 .. Len + 1) := Buf (1 .. Len);
+               Ndigs := Len + 1;
+            end if;
 
-            else
-               for K in 1 .. Maxdigs - Len loop
-                  Digs (Ndigs + K) := '0';
-               end loop;
+         --  Or else pad the output with zeroes up to Maxdigs
 
-               for K in 1 .. Len loop
-                  Digs (Ndigs + Maxdigs - Len + K) := Buf (K);
-               end loop;
+         else
+            for K in 1 .. Maxdigs - Len loop
+               Digs (Ndigs + K) := '0';
+            end loop;
 
-               Ndigs := Ndigs + Maxdigs;
-            end if;
+            for K in 1 .. Len loop
+               Digs (Ndigs + Maxdigs - Len + K) := Buf (K);
+            end loop;
 
-            Scale := Scale + Maxdigs;
+            Ndigs := Ndigs + Maxdigs;
          end if;
+
+         Scale := Scale + Maxdigs;
+         J := J + 1;
       end loop;
 
       --  If no digit was output, this is zero