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