From: Sheri Bernstein <bernst...@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(-) 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 -- 2.42.0