From 01173c413da8d1d14b241cb3239cd72c70563887 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Thu, 26 Aug 2021 06:56:26 +0200 Subject: vhdl-evaluation: check integer evaluations fit in base type. Fix #1834 --- src/vhdl/translate/trans-chap3.adb | 13 +++++++++---- src/vhdl/vhdl-evaluation.adb | 35 ++++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 11 deletions(-) (limited to 'src/vhdl') diff --git a/src/vhdl/translate/trans-chap3.adb b/src/vhdl/translate/trans-chap3.adb index e782d2d11..7f135a748 100644 --- a/src/vhdl/translate/trans-chap3.adb +++ b/src/vhdl/translate/trans-chap3.adb @@ -2223,10 +2223,15 @@ package body Trans.Chap3 is else -- Bounds are locally static. Get_Low_High_Limit (Rng, Lo, Hi); - Subtype_Info.S.Nocheck_Hi := - Is_Equal_Limit (Hi, True, Def, Base_Info.Type_Mode); - Subtype_Info.S.Nocheck_Low := - Is_Equal_Limit (Lo, False, Def, Base_Info.Type_Mode); + if Is_Overflow_Literal (Hi) or else Is_Overflow_Literal (Lo) then + Subtype_Info.S.Nocheck_Hi := True; + Subtype_Info.S.Nocheck_Low := True; + else + Subtype_Info.S.Nocheck_Hi := + Is_Equal_Limit (Hi, True, Def, Base_Info.Type_Mode); + Subtype_Info.S.Nocheck_Low := + Is_Equal_Limit (Lo, False, Def, Base_Info.Type_Mode); + end if; end if; end Create_Subtype_Info_From_Type; diff --git a/src/vhdl/vhdl-evaluation.adb b/src/vhdl/vhdl-evaluation.adb index 32b337e73..3b868b576 100644 --- a/src/vhdl/vhdl-evaluation.adb +++ b/src/vhdl/vhdl-evaluation.adb @@ -312,6 +312,24 @@ package body Vhdl.Evaluation is end case; end Build_Extreme_Value; + -- Check VAL fits in the base type. + function Build_Integer_Check (Val : Int64; Origin : Iir) + return Iir_Integer_Literal + is + Atype : constant Iir := Get_Base_Type (Get_Type (Origin)); + subtype Rng_32 is Int64 range Int64 (Int32'First) .. Int64 (Int32'Last); + begin + if Get_Scalar_Size (Atype) = Scalar_32 + and then Val not in Rng_32 + then + Warning_Msg_Sem (Warnid_Runtime_Error, +Origin, + "arithmetic overflow in static expression"); + return Build_Overflow (Origin); + end if; + + return Build_Integer (Val, Origin); + end Build_Integer_Check; + -- A_RANGE is a range expression, whose type, location, expr_staticness, -- left_limit and direction are set. -- Type of A_RANGE must have a range_constraint. @@ -1641,34 +1659,37 @@ package body Vhdl.Evaluation is case Func is when Iir_Predefined_Integer_Plus => - return Build_Integer (Get_Value (Left) + Get_Value (Right), Orig); + return Build_Integer_Check + (Get_Value (Left) + Get_Value (Right), Orig); when Iir_Predefined_Integer_Minus => - return Build_Integer (Get_Value (Left) - Get_Value (Right), Orig); + return Build_Integer_Check + (Get_Value (Left) - Get_Value (Right), Orig); when Iir_Predefined_Integer_Mul => - return Build_Integer (Get_Value (Left) * Get_Value (Right), Orig); + return Build_Integer_Check + (Get_Value (Left) * Get_Value (Right), Orig); when Iir_Predefined_Integer_Div => if Check_Integer_Division_By_Zero (Orig, Right) then - return Build_Integer + return Build_Integer_Check (Get_Value (Left) / Get_Value (Right), Orig); else return Build_Overflow (Orig); end if; when Iir_Predefined_Integer_Mod => if Check_Integer_Division_By_Zero (Orig, Right) then - return Build_Integer + return Build_Integer_Check (Get_Value (Left) mod Get_Value (Right), Orig); else return Build_Overflow (Orig); end if; when Iir_Predefined_Integer_Rem => if Check_Integer_Division_By_Zero (Orig, Right) then - return Build_Integer + return Build_Integer_Check (Get_Value (Left) rem Get_Value (Right), Orig); else return Build_Overflow (Orig); end if; when Iir_Predefined_Integer_Exp => - return Build_Integer + return Build_Integer_Check (Get_Value (Left) ** Integer (Get_Value (Right)), Orig); when Iir_Predefined_Integer_Equality => -- cgit v1.2.3