aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-09-30 07:37:02 +0200
committerTristan Gingold <tgingold@free.fr>2019-09-30 07:37:02 +0200
commitbf30078cae1fd5631c3ab8a19dfa6693aeb2c94b (patch)
tree4c11dadd132688a2f8dd4ca8e95cec77b3f515dc
parentc93cda5fc40a252f52b00745e1126abf6f06d567 (diff)
downloadghdl-bf30078cae1fd5631c3ab8a19dfa6693aeb2c94b.tar.gz
ghdl-bf30078cae1fd5631c3ab8a19dfa6693aeb2c94b.tar.bz2
ghdl-bf30078cae1fd5631c3ab8a19dfa6693aeb2c94b.zip
synth: check matching bounds for array equality. Fix #947
-rw-r--r--src/synth/synth-oper.adb10
-rw-r--r--src/synth/synth-values.adb48
-rw-r--r--src/synth/synth-values.ads2
3 files changed, 56 insertions, 4 deletions
diff --git a/src/synth/synth-oper.adb b/src/synth/synth-oper.adb
index f2ab7cb5b..b9926aff0 100644
--- a/src/synth/synth-oper.adb
+++ b/src/synth/synth-oper.adb
@@ -419,11 +419,13 @@ package body Synth.Oper is
return Create_Value_Discrete
(Boolean'Pos (Is_Equal (Left, Right)), Boolean_Type);
end if;
- if Is_Vector_Type (Left_Type) then
- return Synth_Compare (Id_Eq);
- else
- raise Internal_Error;
+ if not Is_Matching_Bounds (Left.Typ, Right.Typ) then
+ Warning_Msg_Synth
+ (+Expr,
+ "length of '=' operands doesn't match, result is false");
+ return Create_Value_Discrete (0, Boolean_Type);
end if;
+ return Synth_Compare (Id_Eq);
when Iir_Predefined_Array_Inequality =>
-- TODO: check size, handle non-vector.
if Is_Vector_Type (Left_Type) then
diff --git a/src/synth/synth-values.adb b/src/synth/synth-values.adb
index c7f059c67..ed30ffd3d 100644
--- a/src/synth/synth-values.adb
+++ b/src/synth/synth-values.adb
@@ -595,6 +595,54 @@ package body Synth.Values is
return Atype.W;
end Get_Type_Width;
+ function Get_Bound_Length (L : Type_Acc; Dim : Iir_Index32) return Width is
+ begin
+ case L.Kind is
+ when Type_Vector =>
+ if Dim /= 1 then
+ raise Internal_Error;
+ end if;
+ return L.Vbound.Len;
+ when Type_Slice =>
+ if Dim /= 1 then
+ raise Internal_Error;
+ end if;
+ return L.W;
+ when Type_Array =>
+ return L.Abounds.D (Dim).Len;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Get_Bound_Length;
+
+ function Is_Matching_Bounds (L, R : Type_Acc) return Boolean is
+ begin
+ case L.Kind is
+ when Type_Bit
+ | Type_Logic
+ | Type_Discrete
+ | Type_Float =>
+ pragma Assert (L.Kind = R.Kind);
+ return True;
+ when Type_Vector
+ | Type_Slice =>
+ return Get_Bound_Length (L, 1) = Get_Bound_Length (R, 1);
+ when Type_Array =>
+ for I in L.Abounds.D'Range loop
+ if Get_Bound_Length (L, I) /= Get_Bound_Length (R, I) then
+ return False;
+ end if;
+ end loop;
+ return True;
+ when Type_Unbounded_Array
+ | Type_Unbounded_Vector =>
+ raise Internal_Error;
+ when Type_Record =>
+ -- FIXME: handle vhdl-08
+ return True;
+ end case;
+ end Is_Matching_Bounds;
+
function Create_Value_Default (Typ : Type_Acc) return Value_Acc is
begin
case Typ.Kind is
diff --git a/src/synth/synth-values.ads b/src/synth/synth-values.ads
index 73aefde2e..f897bdf8a 100644
--- a/src/synth/synth-values.ads
+++ b/src/synth/synth-values.ads
@@ -293,6 +293,8 @@ package Synth.Values is
-- sub-elements.
function Get_Array_Flat_Length (Typ : Type_Acc) return Width;
+ function Is_Matching_Bounds (L, R : Type_Acc) return Boolean;
+
function Get_Type_Width (Atype : Type_Acc) return Width;
-- Create a default initial value for TYP.