If a bounded string slice operation has a lower bound less than the higher bound minus one, the resulting length can be negative leading to failures and exceptions.
The following must compile and execute cleanly: 1. with Ada.Strings.Bounded; use Ada.Strings.Bounded; 2. with Ada.Text_IO; use Ada.Text_IO; 3. procedure BSlice is 4. package BS is new Generic_Bounded_Length (1000); 5. use BS; 6. S : Bounded_String := To_Bounded_String ("Hello World!"); 7. T : Bounded_String := Bounded_Slice (S, 10, 1); 8. begin 9. Put_Line (Length_Range'Image (Length (S))); 10. Put_line (Length_Range'Image (Length (T))); 11. end Bslice; Generating the output: 12 0 Tested on x86_64-pc-linux-gnu, committed on trunk 2015-03-04 Robert Dewar <de...@adacore.com> * a-strsup.adb (Super_Slice): Deal with super flat case.
Index: a-strsup.adb =================================================================== --- a-strsup.adb (revision 221175) +++ a-strsup.adb (working copy) @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2003-2014, Free Software Foundation, Inc. -- +-- Copyright (C) 2003-2015, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -1473,6 +1473,9 @@ raise Index_Error; end if; + -- Note: in this case, superflat bounds are not a problem, we just + -- get the null string in accordance with normal Ada slice rules. + R := Source.Data (Low .. High); end return; end Super_Slice; @@ -1490,7 +1493,9 @@ raise Index_Error; end if; - Result.Current_Length := High - Low + 1; + -- Note: the Max operation here deals with the superflat case + + Result.Current_Length := Integer'Max (0, High - Low + 1); Result.Data (1 .. Result.Current_Length) := Source.Data (Low .. High); end return; end Super_Slice; @@ -1506,10 +1511,12 @@ or else High > Source.Current_Length then raise Index_Error; - else - Target.Current_Length := High - Low + 1; - Target.Data (1 .. Target.Current_Length) := Source.Data (Low .. High); end if; + + -- Note: the Max operation here deals with the superflat case + + Target.Current_Length := Integer'Max (0, High - Low + 1); + Target.Data (1 .. Target.Current_Length) := Source.Data (Low .. High); end Super_Slice; ----------------