aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl/evaluation.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/vhdl/evaluation.adb')
-rw-r--r--src/vhdl/evaluation.adb75
1 files changed, 68 insertions, 7 deletions
diff --git a/src/vhdl/evaluation.adb b/src/vhdl/evaluation.adb
index 589ab1fb2..c2283c57c 100644
--- a/src/vhdl/evaluation.adb
+++ b/src/vhdl/evaluation.adb
@@ -1866,9 +1866,7 @@ package body Evaluation is
Res := Build_Constant (Val, Conv);
if Get_Constraint_State (Conv_Type) = Fully_Constrained then
Set_Type (Res, Conv_Type);
- if Eval_Discrete_Type_Length (Conv_Index_Type)
- /= Eval_Discrete_Type_Length (Val_Index_Type)
- then
+ if not Eval_Is_In_Bound (Val, Conv_Type) then
Warning_Msg_Sem
("non matching length in type conversion", Conv);
return Build_Overflow (Conv);
@@ -2471,7 +2469,7 @@ package body Evaluation is
return True;
end Eval_Fp_In_Range;
- -- Return TRUE if literal EXPR is in SUB_TYPE bounds.
+ -- Return FALSE if literal EXPR is not in SUB_TYPE bounds.
function Eval_Is_In_Bound (Expr : Iir; Sub_Type : Iir) return Boolean
is
Type_Range : Iir;
@@ -2494,28 +2492,91 @@ package body Evaluation is
case Get_Kind (Sub_Type) is
when Iir_Kind_Integer_Subtype_Definition =>
+ if Get_Expr_Staticness (Expr) /= Locally
+ or else Get_Type_Staticness (Sub_Type) /= Locally
+ then
+ return True;
+ end if;
Type_Range := Get_Range_Constraint (Sub_Type);
return Eval_Int_In_Range (Get_Value (Val), Type_Range);
when Iir_Kind_Floating_Subtype_Definition =>
+ if Get_Expr_Staticness (Expr) /= Locally
+ or else Get_Type_Staticness (Sub_Type) /= Locally
+ then
+ return True;
+ end if;
Type_Range := Get_Range_Constraint (Sub_Type);
return Eval_Fp_In_Range (Get_Fp_Value (Val), Type_Range);
when Iir_Kind_Enumeration_Subtype_Definition
| Iir_Kind_Enumeration_Type_Definition =>
+ if Get_Expr_Staticness (Expr) /= Locally
+ or else Get_Type_Staticness (Sub_Type) /= Locally
+ then
+ return True;
+ end if;
-- A check is required for an enumeration type definition for
-- 'val attribute.
Type_Range := Get_Range_Constraint (Sub_Type);
return Eval_Int_In_Range
(Iir_Int64 (Get_Enum_Pos (Val)), Type_Range);
when Iir_Kind_Physical_Subtype_Definition =>
+ if Get_Expr_Staticness (Expr) /= Locally
+ or else Get_Type_Staticness (Sub_Type) /= Locally
+ then
+ return True;
+ end if;
Type_Range := Get_Range_Constraint (Sub_Type);
return Eval_Phys_In_Range (Get_Physical_Value (Val), Type_Range);
when Iir_Kind_Base_Attribute =>
+ if Get_Expr_Staticness (Expr) /= Locally
+ or else Get_Type_Staticness (Sub_Type) /= Locally
+ then
+ return True;
+ end if;
return Eval_Is_In_Bound (Val, Get_Type (Sub_Type));
- when Iir_Kind_Array_Subtype_Definition
- | Iir_Kind_Array_Type_Definition
- | Iir_Kind_Record_Type_Definition =>
+ when Iir_Kind_Array_Subtype_Definition =>
+ declare
+ Val_Type : constant Iir := Get_Type (Val);
+ begin
+ if Get_Constraint_State (Sub_Type) /= Fully_Constrained
+ or else
+ Get_Kind (Val_Type) /= Iir_Kind_Array_Subtype_Definition
+ or else
+ Get_Constraint_State (Val_Type) /= Fully_Constrained
+ then
+ -- Cannot say no.
+ return True;
+ end if;
+ declare
+ E_Indexes : constant Iir_List :=
+ Get_Index_Subtype_List (Val_Type);
+ T_Indexes : constant Iir_List :=
+ Get_Index_Subtype_List (Sub_Type);
+ E_El : Iir;
+ T_El : Iir;
+ begin
+ for I in Natural loop
+ E_El := Get_Index_Type (E_Indexes, I);
+ T_El := Get_Index_Type (T_Indexes, I);
+ exit when E_El = Null_Iir and T_El = Null_Iir;
+
+ if Get_Type_Staticness (E_El) = Locally
+ and then Get_Type_Staticness (T_El) = Locally
+ and then (Eval_Discrete_Type_Length (E_El)
+ /= Eval_Discrete_Type_Length (T_El))
+ then
+ return False;
+ end if;
+ end loop;
+ return True;
+ end;
+ end;
+
+ when Iir_Kind_Array_Type_Definition
+ | Iir_Kind_Record_Type_Definition
+ | Iir_Kind_Record_Subtype_Definition =>
-- FIXME: do it.
return True;