aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2021-08-26 06:56:26 +0200
committerTristan Gingold <tgingold@free.fr>2021-08-26 06:56:26 +0200
commit01173c413da8d1d14b241cb3239cd72c70563887 (patch)
tree5e977088592e3a9948e27f005729d9de82df84a9 /src/vhdl
parent243bb15efb6e7573a278f19b22eaffa43c399714 (diff)
downloadghdl-01173c413da8d1d14b241cb3239cd72c70563887.tar.gz
ghdl-01173c413da8d1d14b241cb3239cd72c70563887.tar.bz2
ghdl-01173c413da8d1d14b241cb3239cd72c70563887.zip
vhdl-evaluation: check integer evaluations fit in base type. Fix #1834
Diffstat (limited to 'src/vhdl')
-rw-r--r--src/vhdl/translate/trans-chap3.adb13
-rw-r--r--src/vhdl/vhdl-evaluation.adb35
2 files changed, 37 insertions, 11 deletions
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 =>