When overflow checking is enabled, the front end generates range checks
on the indexing of a slice with a bound of the form Boolean'Pos (not X)
that get mistranslated by gigi when optimization is enabled. The checks
should not have been generated in the first place (one is a tautological
full range check and the other redundantly tests that the result of
Boolean'Pos is >= 1), and were only generated because of a missing guard
in Checks.Determine_Range that resulted in a bogus comparison of bounds
against No_Uint.

The following test must compile and execute quietly with -gnato and -O:

$ gnatmake -gnato -O boolean_slice_bound_bug

procedure Boolean_Slice_Bound_Bug is

   procedure Proc (B : Boolean) is
      S : constant String (1 .. 1) := (others => 'X');
   begin
      if S (1 .. Boolean'Pos (not B)) /= "X" then
         raise Program_Error;
      end if;
   end Proc;

begin
   Proc (False);
end Boolean_Slice_Bound_Bug;

Tested on x86_64-pc-linux-gnu, committed on trunk

2011-09-02  Gary Dismukes  <dismu...@adacore.com>

        * checks.adb: (Determine_Range): Add test of OK1 to prevent the early
        return done when overflow checks are enabled, since comparisons against
        Lor and Hir should not be done when OK1 is False.

Index: checks.adb
===================================================================
--- checks.adb  (revision 178381)
+++ checks.adb  (working copy)
@@ -3479,10 +3479,11 @@
       --  to restrict the possible range of results.
 
       --  If one of the computed bounds is outside the range of the base type,
-      --  the expression may raise an exception and we better indicate that
+      --  the expression may raise an exception and we had better indicate that
       --  the evaluation has failed, at least if checks are enabled.
 
-      if Enable_Overflow_Checks
+      if OK1
+        and then Enable_Overflow_Checks
         and then not Is_Entity_Name (N)
         and then (Lor < Lo or else Hir > Hi)
       then

Reply via email to