diff options
author | Yannick Moy <moy@adacore.com> | 2020-12-16 14:37:22 +0100 |
---|---|---|
committer | Pierre-Marie de Rodat <derodat@adacore.com> | 2021-04-29 04:00:48 -0400 |
commit | b626569a56c5b35e4c5a10ba7f0abd5d8b4fd0e7 (patch) | |
tree | d02c4bcb45c859bfeaedf8bf68e9e926eb5c80b1 /gcc | |
parent | 4068698c47ff67bf48edf5c21a386204de370aaf (diff) | |
download | gcc-b626569a56c5b35e4c5a10ba7f0abd5d8b4fd0e7.zip gcc-b626569a56c5b35e4c5a10ba7f0abd5d8b4fd0e7.tar.gz gcc-b626569a56c5b35e4c5a10ba7f0abd5d8b4fd0e7.tar.bz2 |
[Ada] Fix evaluation of expressions in inlined code
gcc/ada/
* sem_eval.adb (Check_Non_Static_Context_For_Overflow): Apply
compile-time checking for overflows in non-static contexts
including inlined code.
(Eval_Arithmetic_Op): Use the new procedure.
(Eval_Unary_Op, Eval_Op_Expon): Add call to the new procedure.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ada/sem_eval.adb | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb index 3ccf3a0..e3b4650 100644 --- a/gcc/ada/sem_eval.adb +++ b/gcc/ada/sem_eval.adb @@ -142,6 +142,16 @@ package body Sem_Eval is -- Local Subprograms -- ----------------------- + procedure Check_Non_Static_Context_For_Overflow + (N : Node_Id; + Stat : Boolean; + Result : Uint); + -- For a signed integer type, check non-static overflow in Result when + -- Stat is False. This applies also inside inlined code, where the static + -- property may be an effect of the inlining, which should not be allowed + -- to remove run-time checks (whether during compilation, or even more + -- crucially in the special inlining-for-proof in GNATprove mode). + function Choice_Matches (Expr : Node_Id; Choice : Node_Id) return Match_Result; @@ -649,6 +659,34 @@ package body Sem_Eval is end if; end Check_Non_Static_Context; + ------------------------------------------- + -- Check_Non_Static_Context_For_Overflow -- + ------------------------------------------- + + procedure Check_Non_Static_Context_For_Overflow + (N : Node_Id; + Stat : Boolean; + Result : Uint) + is + begin + if (not Stat or else In_Inlined_Body) + and then Is_Signed_Integer_Type (Etype (N)) + then + declare + BT : constant Entity_Id := Base_Type (Etype (N)); + Lo : constant Uint := Expr_Value (Type_Low_Bound (BT)); + Hi : constant Uint := Expr_Value (Type_High_Bound (BT)); + begin + if Result < Lo or else Result > Hi then + Apply_Compile_Time_Constraint_Error + (N, "value not in range of }??", + CE_Overflow_Check_Failed, + Ent => BT); + end if; + end; + end if; + end Check_Non_Static_Context_For_Overflow; + --------------------------------- -- Check_String_Literal_Length -- --------------------------------- @@ -2143,25 +2181,10 @@ package body Sem_Eval is if Is_Modular_Integer_Type (Ltype) then Result := Result mod Modulus (Ltype); - - -- For a signed integer type, check non-static overflow - - elsif (not Stat) and then Is_Signed_Integer_Type (Ltype) then - declare - BT : constant Entity_Id := Base_Type (Ltype); - Lo : constant Uint := Expr_Value (Type_Low_Bound (BT)); - Hi : constant Uint := Expr_Value (Type_High_Bound (BT)); - begin - if Result < Lo or else Result > Hi then - Apply_Compile_Time_Constraint_Error - (N, "value not in range of }??", - CE_Overflow_Check_Failed, - Ent => BT); - return; - end if; - end; end if; + Check_Non_Static_Context_For_Overflow (N, Stat, Result); + -- If we get here we can fold the result Fold_Uint (N, Result, Stat); @@ -3202,6 +3225,8 @@ package body Sem_Eval is Result := Result mod Modulus (Etype (N)); end if; + Check_Non_Static_Context_For_Overflow (N, Stat, Result); + Fold_Uint (N, Result, Stat); end if; end; @@ -4375,6 +4400,8 @@ package body Sem_Eval is Result := abs Rint; end if; + Check_Non_Static_Context_For_Overflow (N, Stat, Result); + Fold_Uint (N, Result, Stat); end; |