This change removes some unnecessary range checks. The following test compiled with -gnatdt -gnatc:
1. procedure RCInteger (X : Integer) is 2. type YT is new Integer; 3. Y : constant YT := YT(X) * YT(X); 4. begin 5. null; 6. end; generates a tree file that has no instances of the Do_Range_Check flag being set (the multiplication in line 3 needs an overflow check, but not a subsequent range check). This test, also compiled with -gnatdt -gnatc: 1. procedure Assign_Int (X : in out Integer) is 2. Tmp : Integer := X + 1; 3. Pos : Positive := X + 2; 4. begin 5. X := X + 3; 6. end Assign_Int; Generates a tree file with one instance of Do_Range_Check being set. Line 3 needs a range check, but line 2 does not. Tested on x86_64-pc-linux-gnu, committed on trunk 2014-08-04 Robert Dewar <de...@adacore.com> * sem_eval.adb (Test_In_Range): Always in range for Is_Known_Valid target type, where input type has smaller or equal size and does not have biased rep.
Index: sem_eval.adb =================================================================== --- sem_eval.adb (revision 213530) +++ sem_eval.adb (working copy) @@ -6193,6 +6193,18 @@ then return In_Range; + -- Another special case. For signed integer types, if the target type + -- has Is_Known_Valid set, and the source type does not have a larger + -- size, then the source value must be in range. We exclude biased + -- types, because they bizarrely can generate out of range values. + + elsif Is_Signed_Integer_Type (Etype (N)) + and then Is_Known_Valid (Typ) + and then Esize (Etype (N)) <= Esize (Typ) + and then not Has_Biased_Representation (Etype (N)) + then + return In_Range; + -- For all other cases, result is unknown else