This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Fix bugs in Integer'Value


Tested on i686-linux, committed on trunk

Integer'Value("- 5") was returning -5.  Now it correctly raises
Constraint_Error; the non-leading blank is wrong.  This was happening
because Scan_Integer was skipping leading-blanks-and-sign, then calling
Scan_Unsigned which was ALSO skipping leading-blanks-and-sign.
This test:

with Ada.Text_IO; use Ada.Text_IO;

procedure Value_Test is

   generic
      Type_Name : String;
      type My_Int is (<>);
   procedure Generic_Test (Image : String);

   procedure Generic_Test (Image : String) is
      -- Test cases where 'Value is expected to fail.
      Val: My_Int;
   begin
      Put (Type_Name & "'Value (""" & Image & """) --> ");
      Val := My_Int'Value (Image);
      Put_Line (My_Int'Image (Val) & " -- ERROR!");
   exception
      when Constraint_Error =>
         Put_Line ("Constraint_Error raised -- OK.");
   end Generic_Test;

   procedure Integer_Test is new Generic_Test ("Integer", Integer);
   procedure Long_Integer_Test is new Generic_Test ("Long_Integer", Long_Integer);

   type Modular is mod 1000;
   procedure Modular_Test is new Generic_Test ("Modular", Modular);

   X: Integer := Integer'First;
   Most_Negative: constant String := Integer'Image (X);
   Long_X: Long_Integer := Long_Integer'First;
   Long_Most_Negative: constant String := Long_Integer'Image (Long_X);
begin
   Integer_Test ("- 5");
   Integer_Test ("-   5");
   Integer_Test ("--5");
   Integer_Test ("-+5");
   Integer_Test ("+-5");
   Integer_Test ("++5");

   X := Integer'Value (Most_Negative);
   Put_Line ("X = " & Integer'Image (X) & " -- OK.");

   Long_X := Long_Integer'Value (Long_Most_Negative);
   Put_Line ("Long_X = " & Long_Integer'Image (Long_X) & " -- OK.");

   Long_Integer_Test ("- 5");
   Long_Integer_Test ("-   5");
   Long_Integer_Test ("--5");
   Long_Integer_Test ("-+5");
   Long_Integer_Test ("+-5");
   Long_Integer_Test ("++5");

   Modular_Test ("-0");
   Modular_Test ("-5");
   Modular_Test ("- 5");
   Modular_Test ("-   5");
   Modular_Test ("--5");
   Modular_Test ("-+5");
   Modular_Test ("+-5");
   Modular_Test ("++5");
end Value_Test;

Should produce this output:
Integer'Value ("- 5") --> Constraint_Error raised -- OK.
Integer'Value ("-   5") --> Constraint_Error raised -- OK.
Integer'Value ("--5") --> Constraint_Error raised -- OK.
Integer'Value ("-+5") --> Constraint_Error raised -- OK.
Integer'Value ("+-5") --> Constraint_Error raised -- OK.
Integer'Value ("++5") --> Constraint_Error raised -- OK.
X = -2147483648 -- OK.
Long_X = -2147483648 -- OK.
Long_Integer'Value ("- 5") --> Constraint_Error raised -- OK.
Long_Integer'Value ("-   5") --> Constraint_Error raised -- OK.
Long_Integer'Value ("--5") --> Constraint_Error raised -- OK.
Long_Integer'Value ("-+5") --> Constraint_Error raised -- OK.
Long_Integer'Value ("+-5") --> Constraint_Error raised -- OK.
Long_Integer'Value ("++5") --> Constraint_Error raised -- OK.
Modular'Value ("-0") --> Constraint_Error raised -- OK.
Modular'Value ("-5") --> Constraint_Error raised -- OK.
Modular'Value ("- 5") --> Constraint_Error raised -- OK.
Modular'Value ("-   5") --> Constraint_Error raised -- OK.
Modular'Value ("--5") --> Constraint_Error raised -- OK.
Modular'Value ("-+5") --> Constraint_Error raised -- OK.
Modular'Value ("+-5") --> Constraint_Error raised -- OK.
Modular'Value ("++5") --> Constraint_Error raised -- OK.

2006-02-13  Bob Duff  <duff@adacore.com>

	* s-valint.adb (Scan_Integer): Call Scan_Raw_Unsigned instead of
	Scan_Unsigned, so we do not scan leading blanks and sign twice.
	Integer'Value("- 5") and Integer'Value("-+5") now correctly
	raise Constraint_Error.

	* s-vallli.adb (Scan_Long_Long_Integer): Call
	Scan_Raw_Long_Long_Unsigned instead of Scan_Long_Long_Unsigned, so we
	do not scan leading blanks and sign twice.
	Integer'Value("- 5") and Integer'Value("-+5") now correctly
	raise Constraint_Error.

	* s-valllu.ads, s-valllu.adb (Scan_Raw_Long_Long_Unsigned,
	Scan_Long_Long_Unsigned): Split out most of the processing from
	Scan_Long_Long_Unsigned out into
	Scan_Raw_Long_Long_Unsigned, so that Val_LLI can call the Raw_ version.
	This prevents scanning leading blanks and sign twice.
	Also fixed a bug: Modular'Value("-0") should raise Constraint_Error
	See RM-3.5(44).

	* s-valuns.ads, s-valuns.adb (Scan_Raw_Unsigned, Scan_Unsigned): Split
	out most of the processing from Scan_Unsigned out into
	Scan_Raw_Unsigned, so that Val_LLI can call the Raw_ version.
	This prevents scanning leading blanks and sign twice.

	* s-valuti.ads, s-valuti.adb (Scan_Plus_Sign): Add Scan_Plus_Sign, for
	use with Modular'Value attribute.
	(Scan_Plus_Sign): Add Scan_Plus_Sign, for use with Modular'Value
	attribute.

Attachment: difs.82
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]