aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-09-26 09:12:18 +0200
committerTristan Gingold <tgingold@free.fr>2020-09-26 09:12:18 +0200
commit8cb1e16ceb5ee655fc214f1ef8a7abbe807ba4b3 (patch)
tree9e70f33e0c54146785779815f44dac389ecde40d /src/vhdl
parentc389c4fc8b65357e8075731323f4ba188817c134 (diff)
downloadghdl-8cb1e16ceb5ee655fc214f1ef8a7abbe807ba4b3.tar.gz
ghdl-8cb1e16ceb5ee655fc214f1ef8a7abbe807ba4b3.tar.bz2
ghdl-8cb1e16ceb5ee655fc214f1ef8a7abbe807ba4b3.zip
vhdl: evaluate operands of operators, check bounds. For #1475
Diffstat (limited to 'src/vhdl')
-rw-r--r--src/vhdl/vhdl-evaluation.adb20
-rw-r--r--src/vhdl/vhdl-sem_expr.adb24
2 files changed, 30 insertions, 14 deletions
diff --git a/src/vhdl/vhdl-evaluation.adb b/src/vhdl/vhdl-evaluation.adb
index 9206db678..0784c706e 100644
--- a/src/vhdl/vhdl-evaluation.adb
+++ b/src/vhdl/vhdl-evaluation.adb
@@ -36,6 +36,8 @@ package body Vhdl.Evaluation is
-- If FORCE is true, always return a literal.
function Eval_Expr_Keep_Orig (Expr : Iir; Force : Boolean) return Iir;
+ function Eval_Check_Bound (Expr : Iir; Sub_Type : Iir) return Boolean;
+
function Eval_Enum_To_String (Lit : Iir; Orig : Iir) return Iir;
function Eval_Integer_Image (Val : Int64; Orig : Iir) return Iir;
function Eval_Floating_Image (Val : Fp64; Orig : Iir) return Iir;
@@ -3417,8 +3419,9 @@ package body Vhdl.Evaluation is
and then Get_Kind (Atype) in Iir_Kinds_Range_Type_Definition
then
-- Check bounds (as this can be done).
- -- FIXME: create overflow_expr ?
- Eval_Check_Bound (Res, Atype);
+ if not Eval_Check_Bound (Res, Atype) then
+ Res := Build_Overflow (Res, Atype);
+ end if;
end if;
return Res;
@@ -3657,15 +3660,26 @@ package body Vhdl.Evaluation is
end case;
end Eval_Is_In_Bound;
- procedure Eval_Check_Bound (Expr : Iir; Sub_Type : Iir) is
+ function Eval_Check_Bound (Expr : Iir; Sub_Type : Iir) return Boolean is
begin
-- Note: use True not to repeat a message in case of overflow.
if not Eval_Is_In_Bound (Expr, Sub_Type, True) then
Warning_Msg_Sem (Warnid_Runtime_Error, +Expr,
"static expression violates bounds");
+ return False;
+ else
+ return True;
end if;
end Eval_Check_Bound;
+ procedure Eval_Check_Bound (Expr : Iir; Sub_Type : Iir)
+ is
+ Res : Boolean;
+ begin
+ Res := Eval_Check_Bound (Expr, Sub_Type);
+ pragma Unreferenced (Res);
+ end Eval_Check_Bound;
+
function Eval_Is_Range_In_Bound
(A_Range : Iir; Sub_Type : Iir; Any_Dir : Boolean)
return Boolean
diff --git a/src/vhdl/vhdl-sem_expr.adb b/src/vhdl/vhdl-sem_expr.adb
index 0e6d17509..4d6b772b5 100644
--- a/src/vhdl/vhdl-sem_expr.adb
+++ b/src/vhdl/vhdl-sem_expr.adb
@@ -1727,36 +1727,38 @@ package body Vhdl.Sem_Expr is
Is_Dyadic : constant Boolean :=
Get_Kind (Expr) in Iir_Kinds_Dyadic_Operator;
Interface_Chain : Iir;
- Err : Boolean;
- Left : Iir;
- Right : Iir;
+ Err : Boolean;
+ Left : Iir;
+ Left_Type : Iir;
+ Right : Iir;
+ Right_Type : Iir;
begin
Set_Type (Expr, Get_Return_Type (Decl));
Interface_Chain := Get_Interface_Declaration_Chain (Decl);
Err := False;
Left := Get_Left (Expr);
+ Left_Type := Get_Type (Interface_Chain);
if Is_Overloaded (Left) then
- Left := Sem_Expression_Ov
- (Left, Get_Base_Type (Get_Type (Interface_Chain)));
+ Left := Sem_Expression_Ov (Left, Get_Base_Type (Left_Type));
if Left = Null_Iir then
Err := True;
- else
- Set_Left (Expr, Left);
end if;
end if;
+ Left := Eval_Expr_Check_If_Static (Left, Left_Type);
Check_Read (Left);
+ Set_Left (Expr, Left);
if Is_Dyadic then
Right := Get_Right (Expr);
+ Right_Type := Get_Type (Get_Chain (Interface_Chain));
if Is_Overloaded (Right) then
- Right := Sem_Expression_Ov
- (Right, Get_Base_Type (Get_Type (Get_Chain (Interface_Chain))));
+ Right := Sem_Expression_Ov (Right, Get_Base_Type (Right_Type));
if Right = Null_Iir then
Err := True;
- else
- Set_Right (Expr, Right);
end if;
end if;
+ Right := Eval_Expr_Check_If_Static (Right, Right_Type);
Check_Read (Right);
+ Set_Right (Expr, Right);
end if;
if not Err then
Set_Implementation (Expr, Decl);