This patch removes an optimization when evaluating integer literals within qualified expressions that caused checks on if and case expressions to not be generated properly.
------------ -- Source -- ------------ -- call_do_smth.adb with Test; use Test; with Ada.Text_IO; procedure Call_Do_Smth is X : T; Y : T; begin Do_Smth (True, X, Y); Ada.Text_IO.Put_Line (T'Image (X)); Ada.Text_IO.Put_Line (T'Image (Y)); end Call_Do_Smth; -- test.ads package Test with SPARK_Mode is subtype T is Positive range 5 .. 16; procedure Do_Smth (I : Boolean; Oha : out T; Ohb : out T); end Test; -- test.adb package body Test with SPARK_Mode is procedure Do_Smth (I : Boolean; Oha : out T; Ohb : out T) is V : T := T'(if I then 0 else 16); V2 : T := T'(case I is when True => 0, when False => 16); begin Oha := V; Ohb := V2; end Do_Smth; end Test; ---------------------------- -- Compilation and output -- ---------------------------- $ gnatmake -q call_do_smth.adb test.adb:6:13: value not in range of type "T" defined at test.ads:3 test.adb:6:13: "Constraint_Error" would have been raised at run time test.adb:11:27: value not in range of type "T" defined at test.ads:3 test.adb:11:27: "Constraint_Error" would have been raised at run time gnatmake: "test.adb" compilation error Tested on x86_64-pc-linux-gnu, committed on trunk 2017-01-23 Justin Squirek <squi...@adacore.com> * sem_eval.adb (Eval_Integer_Literal): Add special case to avoid optimizing out check if the literal appears in an if-expression.
Index: sem_eval.adb =================================================================== --- sem_eval.adb (revision 244773) +++ sem_eval.adb (working copy) @@ -2682,9 +2682,12 @@ -- If the literal appears in a non-expression context, then it is -- certainly appearing in a non-static context, so check it. This is -- actually a redundant check, since Check_Non_Static_Context would - -- check it, but it seems worth while avoiding the call. + -- check it, but it seems worth while to optimize out the call. - if Nkind (Parent (N)) not in N_Subexpr + -- An exception is made for a literal in an if or case expression + + if (Nkind_In (Parent (N), N_If_Expression, N_Case_Expression_Alternative) + or else Nkind (Parent (N)) not in N_Subexpr) and then not In_Any_Integer_Context then Check_Non_Static_Context (N);