diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-09-30 07:37:02 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-09-30 07:37:02 +0200 |
commit | bf30078cae1fd5631c3ab8a19dfa6693aeb2c94b (patch) | |
tree | 4c11dadd132688a2f8dd4ca8e95cec77b3f515dc | |
parent | c93cda5fc40a252f52b00745e1126abf6f06d567 (diff) | |
download | ghdl-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.adb | 10 | ||||
-rw-r--r-- | src/synth/synth-values.adb | 48 | ||||
-rw-r--r-- | src/synth/synth-values.ads | 2 |
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. |