aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2022-02-17 07:49:59 +0100
committerTristan Gingold <tgingold@free.fr>2022-02-17 07:51:02 +0100
commit7257b70ca6a7380a3c739e62bf3c9ca69f0dd223 (patch)
tree727cfbc01d4737e19c4d79f14de96e458f71a0ed
parenta4f663eb442310aa17d895d267a9e212c54c5efe (diff)
downloadghdl-7257b70ca6a7380a3c739e62bf3c9ca69f0dd223.tar.gz
ghdl-7257b70ca6a7380a3c739e62bf3c9ca69f0dd223.tar.bz2
ghdl-7257b70ca6a7380a3c739e62bf3c9ca69f0dd223.zip
synth: properly propagate bound errors. Fix #1972
-rw-r--r--src/synth/synth-vhdl_expr.adb39
-rw-r--r--src/synth/synth-vhdl_expr.ads3
-rw-r--r--src/synth/synth-vhdl_insts.adb5
-rw-r--r--src/synth/synth-vhdl_stmts.adb7
4 files changed, 38 insertions, 16 deletions
diff --git a/src/synth/synth-vhdl_expr.adb b/src/synth/synth-vhdl_expr.adb
index ee691d8f5..c7eb117b6 100644
--- a/src/synth/synth-vhdl_expr.adb
+++ b/src/synth/synth-vhdl_expr.adb
@@ -893,6 +893,12 @@ package body Synth.Vhdl_Expr is
end case;
end Synth_Name;
+ procedure Bound_Error (Syn_Inst : Synth_Instance_Acc; Loc : Node) is
+ begin
+ Error_Msg_Synth (+Loc, "index not within bounds");
+ Elab.Debugger.Debug_Error (Syn_Inst, Loc);
+ end Bound_Error;
+
-- Convert index IDX in PFX to an offset.
-- SYN_INST and LOC are used in case of error.
function Index_To_Offset
@@ -902,8 +908,7 @@ package body Synth.Vhdl_Expr is
Res : Value_Offsets;
begin
if not In_Bounds (Bnd, Int32 (Idx)) then
- Error_Msg_Synth (+Loc, "index not within bounds");
- Elab.Debugger.Debug_Error (Syn_Inst, Loc);
+ Bound_Error (Syn_Inst, Loc);
return (0, 0);
end if;
@@ -1000,13 +1005,15 @@ package body Synth.Vhdl_Expr is
Name : Node;
Pfx_Type : Type_Acc;
Voff : out Net;
- Off : out Value_Offsets)
+ Off : out Value_Offsets;
+ Error : out Boolean)
is
Ctxt : constant Context_Acc := Get_Build (Syn_Inst);
Indexes : constant Iir_Flist := Get_Index_List (Name);
El_Typ : constant Type_Acc := Get_Array_Element (Pfx_Type);
Idx_Expr : Node;
Idx_Val : Valtyp;
+ Idx : Int64;
Bnd : Bound_Type;
Stride : Uns32;
Ivoff : Net;
@@ -1014,6 +1021,7 @@ package body Synth.Vhdl_Expr is
begin
Voff := No_Net;
Off := (0, 0);
+ Error := False;
Stride := 1;
for I in reverse Flist_First .. Flist_Last (Indexes) loop
@@ -1022,9 +1030,8 @@ package body Synth.Vhdl_Expr is
-- Use the base type as the subtype of the index is not synth-ed.
Idx_Val := Synth_Expression_With_Basetype (Syn_Inst, Idx_Expr);
if Idx_Val = No_Valtyp then
- -- Propagate errorc
- Voff := No_Net;
- Off := (0, 0);
+ -- Propagate error.
+ Error := True;
return;
end if;
@@ -1033,11 +1040,17 @@ package body Synth.Vhdl_Expr is
Bnd := Get_Array_Bound (Pfx_Type, Dim_Type (I + 1));
if Is_Static_Val (Idx_Val.Val) then
- Idx_Off := Index_To_Offset (Syn_Inst, Bnd,
- Get_Static_Discrete (Idx_Val), Name);
- Off.Net_Off := Off.Net_Off + Idx_Off.Net_Off * Stride * El_Typ.W;
- Off.Mem_Off := Off.Mem_Off
- + Idx_Off.Mem_Off * Size_Type (Stride) * El_Typ.Sz;
+ Idx := Get_Static_Discrete (Idx_Val);
+ if not In_Bounds (Bnd, Int32 (Idx)) then
+ Bound_Error (Syn_Inst, Name);
+ Error := True;
+ else
+ Idx_Off := Index_To_Offset (Syn_Inst, Bnd, Idx, Name);
+ Off.Net_Off := Off.Net_Off
+ + Idx_Off.Net_Off * Stride * El_Typ.W;
+ Off.Mem_Off := Off.Mem_Off
+ + Idx_Off.Mem_Off * Size_Type (Stride) * El_Typ.Sz;
+ end if;
else
Ivoff := Dyn_Index_To_Offset (Ctxt, Bnd, Idx_Val, Name);
Ivoff := Build_Memidx
@@ -2202,6 +2215,10 @@ package body Synth.Vhdl_Expr is
Dyn : Dyn_Name;
begin
Synth_Assignment_Prefix (Syn_Inst, Expr, Base, Typ, Off, Dyn);
+ if Base = No_Valtyp then
+ -- Propagate error.
+ return No_Valtyp;
+ end if;
if Dyn.Voff = No_Net and then Is_Static (Base.Val) then
Res := Create_Value_Memory (Typ);
Copy_Memory
diff --git a/src/synth/synth-vhdl_expr.ads b/src/synth/synth-vhdl_expr.ads
index 7081aef95..33b908de3 100644
--- a/src/synth/synth-vhdl_expr.ads
+++ b/src/synth/synth-vhdl_expr.ads
@@ -119,7 +119,8 @@ package Synth.Vhdl_Expr is
Name : Node;
Pfx_Type : Type_Acc;
Voff : out Net;
- Off : out Value_Offsets);
+ Off : out Value_Offsets;
+ Error : out Boolean);
-- Conversion to logic vector.
type Digit_Index is new Natural;
diff --git a/src/synth/synth-vhdl_insts.adb b/src/synth/synth-vhdl_insts.adb
index b02d2df69..cd6f55e2a 100644
--- a/src/synth/synth-vhdl_insts.adb
+++ b/src/synth/synth-vhdl_insts.adb
@@ -638,11 +638,12 @@ package body Synth.Vhdl_Insts is
declare
Voff : Net;
Arr_Off : Value_Offsets;
+ Err : Boolean;
begin
Synth_Individual_Prefix
(Syn_Inst, Inter_Inst, Get_Prefix (Formal), Off, Typ);
- Synth_Indexed_Name (Syn_Inst, Formal, Typ, Voff, Arr_Off);
- if Voff /= No_Net then
+ Synth_Indexed_Name (Syn_Inst, Formal, Typ, Voff, Arr_Off, Err);
+ if Voff /= No_Net or Err then
raise Internal_Error;
end if;
Off := Off + Arr_Off.Net_Off;
diff --git a/src/synth/synth-vhdl_stmts.adb b/src/synth/synth-vhdl_stmts.adb
index df8a851ce..3d8c7bba2 100644
--- a/src/synth/synth-vhdl_stmts.adb
+++ b/src/synth/synth-vhdl_stmts.adb
@@ -144,14 +144,17 @@ package body Synth.Vhdl_Stmts is
declare
Voff : Net;
Off : Value_Offsets;
+ Err : Boolean;
begin
Synth_Assignment_Prefix
(Syn_Inst, Get_Prefix (Pfx),
Dest_Base, Dest_Typ, Dest_Off, Dest_Dyn);
Strip_Const (Dest_Base);
- Synth_Indexed_Name (Syn_Inst, Pfx, Dest_Typ, Voff, Off);
+ Synth_Indexed_Name (Syn_Inst, Pfx, Dest_Typ, Voff, Off, Err);
- if Voff = No_Net then
+ if Err then
+ Dest_Base := No_Valtyp;
+ elsif Voff = No_Net then
-- Static index.
Dest_Off := Dest_Off + Off;
else