[Ada] Suppress warnings on membership test of ranges

For a membership test "X in A .. B", the compiler used to warn if it
could prove that X is within one of the bounds.  For example, if we know
at compile time that X >= A, then the above could be replaced by "X <=
B".

This patch suppresses that warning, because there is really
nothing wrong with the membership test, and programmers sometimes
find it annoying.

gcc/ada/

	* exp_ch4.adb (Expand_N_In): Do not warn in the above-mentioned
	cases.
	* fe.h (Assume_No_Invalid_Values): Remove from fe.h, because
	this is not used in gigi.
	* opt.ads (Assume_No_Invalid_Values): Improve the comment. We
	don't need to "clearly prove"; we can just "prove". Remove the
	comment about fe.h, which is no longer true.
This commit is contained in:
Bob Duff 2022-04-29 08:08:58 -04:00 committed by Pierre-Marie de Rodat
parent ae575e93b6
commit 3cd52053f8
3 changed files with 7 additions and 46 deletions

View File

@ -6388,7 +6388,7 @@ package body Exp_Ch4 is
Lcheck : Compare_Result;
Ucheck : Compare_Result;
Warn1 : constant Boolean :=
Warn : constant Boolean :=
Constant_Condition_Warnings
and then Comes_From_Source (N)
and then not In_Instance;
@ -6397,16 +6397,6 @@ package body Exp_Ch4 is
-- also skip these warnings in an instance since it may be the
-- case that different instantiations have different ranges.
Warn2 : constant Boolean :=
Warn1
and then Nkind (Original_Node (Rop)) = N_Range
and then Is_Integer_Type (Etype (Lo));
-- For the case where only one bound warning is elided, we also
-- insist on an explicit range and an integer type. The reason is
-- that the use of enumeration ranges including an end point is
-- common, as is the use of a subtype name, one of whose bounds is
-- the same as the type of the expression.
begin
-- If test is explicit x'First .. x'Last, replace by valid check
@ -6491,7 +6481,7 @@ package body Exp_Ch4 is
-- legality checks, because we are constant-folding beyond RM 4.9.
if Lcheck = LT or else Ucheck = GT then
if Warn1 then
if Warn then
Error_Msg_N ("?c?range test optimized away", N);
Error_Msg_N ("\?c?value is known to be out of range", N);
end if;
@ -6505,7 +6495,7 @@ package body Exp_Ch4 is
-- since we know we are in range.
elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
if Warn1 then
if Warn then
Error_Msg_N ("?c?range test optimized away", N);
Error_Msg_N ("\?c?value is known to be in range", N);
end if;
@ -6520,11 +6510,6 @@ package body Exp_Ch4 is
-- a comparison against the upper bound.
elsif Lcheck in Compare_GE then
if Warn2 and then not In_Instance then
Error_Msg_N ("??lower bound test optimized away", Lo);
Error_Msg_N ("\??value is known to be in range", Lo);
end if;
Rewrite (N,
Make_Op_Le (Loc,
Left_Opnd => Lop,
@ -6532,16 +6517,9 @@ package body Exp_Ch4 is
Analyze_And_Resolve (N, Restyp);
goto Leave;
-- If upper bound check succeeds and lower bound check is not
-- known to succeed or fail, then replace the range check with
-- a comparison against the lower bound.
-- Inverse of previous case.
elsif Ucheck in Compare_LE then
if Warn2 and then not In_Instance then
Error_Msg_N ("??upper bound test optimized away", Hi);
Error_Msg_N ("\??value is known to be in range", Hi);
end if;
Rewrite (N,
Make_Op_Ge (Loc,
Left_Opnd => Lop,
@ -6555,7 +6533,7 @@ package body Exp_Ch4 is
-- see if we can determine the outcome assuming everything is
-- valid, and if so give an appropriate warning.
if Warn1 and then not Assume_No_Invalid_Values then
if Warn and then not Assume_No_Invalid_Values then
Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => True);
Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => True);
@ -6570,18 +6548,6 @@ package body Exp_Ch4 is
elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
Error_Msg_N
("?c?value can only be out of range if it is invalid", N);
-- Lower bound check succeeds if value is valid
elsif Warn2 and then Lcheck in Compare_GE then
Error_Msg_N
("?c?lower bound check only fails if it is invalid", Lo);
-- Upper bound check succeeds if value is valid
elsif Warn2 and then Ucheck in Compare_LE then
Error_Msg_N
("?c?upper bound check only fails for invalid values", Hi);
end if;
end if;
end;

View File

@ -203,7 +203,6 @@ extern Boolean In_Extended_Main_Code_Unit (Entity_Id);
/* opt: */
#define Ada_Version opt__ada_version
#define Assume_No_Invalid_Values opt__assume_no_invalid_values
#define Back_End_Inlining opt__back_end_inlining
#define Debug_Generated_Code opt__debug_generated_code
#define Enable_128bit_Types opt__enable_128bit_types
@ -220,7 +219,6 @@ typedef enum {
} Ada_Version_Type;
extern Ada_Version_Type Ada_Version;
extern Boolean Assume_No_Invalid_Values;
extern Boolean Back_End_Inlining;
extern Boolean Debug_Generated_Code;
extern Boolean Enable_128bit_Types;

View File

@ -186,12 +186,9 @@ package Opt is
Assume_No_Invalid_Values : Boolean := False;
-- GNAT Normally, in accordance with (RM 13.9.1 (9-11)) the front end
-- assumes that values could have invalid representations, unless it can
-- clearly prove that the values are valid. If this switch is set (by
-- prove that the values are valid. If this switch is set (by -gnatB or
-- pragma Assume_No_Invalid_Values (On)), then the compiler assumes values
-- are valid and in range of their representations. This feature is now
-- fully enabled in the compiler.
-- WARNING: There is a matching C declaration of this variable in fe.h
-- are valid and in range of their representations.
Back_Annotate_Rep_Info : Boolean := False;
-- GNAT