diff options
author | Tristan Gingold <tgingold@free.fr> | 2022-04-22 07:58:33 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2022-04-22 07:58:33 +0200 |
commit | f4ae3a544fcf718802aac3aa59f9b11bd8387b21 (patch) | |
tree | 757a04410290a991946bca399256941a99f28188 /src | |
parent | de8bb483b7adf998644b61119271fb797a1fb032 (diff) | |
download | ghdl-f4ae3a544fcf718802aac3aa59f9b11bd8387b21.tar.gz ghdl-f4ae3a544fcf718802aac3aa59f9b11bd8387b21.tar.bz2 ghdl-f4ae3a544fcf718802aac3aa59f9b11bd8387b21.zip |
vhdl: avoid a crash after errors in associations for packages
Diffstat (limited to 'src')
-rw-r--r-- | src/vhdl/vhdl-sem_decls.adb | 2 | ||||
-rw-r--r-- | src/vhdl/vhdl-sem_inst.adb | 193 | ||||
-rw-r--r-- | src/vhdl/vhdl-utils.adb | 16 |
3 files changed, 115 insertions, 96 deletions
diff --git a/src/vhdl/vhdl-sem_decls.adb b/src/vhdl/vhdl-sem_decls.adb index 8f44e0858..282137e90 100644 --- a/src/vhdl/vhdl-sem_decls.adb +++ b/src/vhdl/vhdl-sem_decls.adb @@ -501,7 +501,7 @@ package body Vhdl.Sem_Decls is -- the uninstantiated_package_name shall denote an uninstantiated -- package declared in a package declaration. Pkg := Sem_Uninstantiated_Package_Name (Inter); - if Pkg = Null_Iir then + if Pkg = Null_Iir or else Is_Error (Pkg) then return; end if; diff --git a/src/vhdl/vhdl-sem_inst.adb b/src/vhdl/vhdl-sem_inst.adb index 3be21e641..f51cd960e 100644 --- a/src/vhdl/vhdl-sem_inst.adb +++ b/src/vhdl/vhdl-sem_inst.adb @@ -927,6 +927,106 @@ package body Vhdl.Sem_Inst is -- In the instance, replace references (and inner references) to interface -- package declaration to the associated package. + procedure Instantiate_Generic_Map (Assoc : Iir; Inter: Iir) is + begin + -- Replace formal reference to the instance. + -- Cf Get_association_Interface + declare + Formal : Iir; + begin + Formal := Get_Formal (Assoc); + if Is_Valid (Formal) then + loop + case Get_Kind (Formal) is + when Iir_Kind_Simple_Name + | Iir_Kind_Operator_Symbol => + Set_Named_Entity + (Formal, Get_Instance (Get_Named_Entity (Formal))); + exit; + when Iir_Kind_Slice_Name + | Iir_Kind_Indexed_Name + | Iir_Kind_Selected_Element => + Formal := Get_Prefix (Formal); + when others => + Error_Kind ("instantiate_generic_map_chain", Formal); + end case; + end loop; + end if; + end; + + case Get_Kind (Assoc) is + when Iir_Kind_Association_Element_By_Expression + | Iir_Kind_Association_Element_By_Individual + | Iir_Kind_Association_Element_Open => + -- If the type of the formal is an interface type also + -- associated by this map, change the type of the formal + -- to the associated type. + declare + Assoc_Formal : constant Iir := + Get_Association_Interface (Assoc, Inter); + Formal_Type : Iir; + Formal_Orig : Iir; + begin + if Assoc_Formal = Null_Iir then + return; + end if; + Formal_Type := Get_Type (Assoc_Formal); + if Get_Kind (Formal_Type) + = Iir_Kind_Interface_Type_Definition + then + -- Type of the formal is an interface type. + -- Check if the interface type was declared in the same + -- interface list: must have the same parent. + Formal_Orig := Get_Origin (Assoc_Formal); + if Get_Parent (Get_Type_Declarator (Formal_Type)) + = Get_Parent (Formal_Orig) + then + Set_Type (Assoc_Formal, Get_Instance (Formal_Type)); + end if; + end if; + end; + when Iir_Kind_Association_Element_Package => + declare + Sub_Inst : constant Iir := + Get_Named_Entity (Get_Actual (Assoc)); + Sub_Pkg_Inter : constant Iir := + Get_Association_Interface (Assoc, Inter); + Sub_Pkg : constant Iir := Get_Origin (Sub_Pkg_Inter); + begin + -- Replace references of interface package to references + -- to the actual package. + Set_Instance (Sub_Pkg, Sub_Inst); + Set_Instance_On_Chain (Get_Generic_Chain (Sub_Pkg), + Get_Generic_Chain (Sub_Inst)); + Set_Instance_On_Chain (Get_Declaration_Chain (Sub_Pkg), + Get_Declaration_Chain (Sub_Inst)); + end; + when Iir_Kind_Association_Element_Type => + -- Replace the incomplete interface type by the actual subtype + -- indication. + declare + Assoc_Inter : constant Iir := + Get_Association_Interface (Assoc, Inter); + Inter_Type_Def : constant Iir := Get_Type (Assoc_Inter); + Actual_Type : constant Iir := Get_Actual_Type (Assoc); + begin + Set_Instance (Inter_Type_Def, Actual_Type); + end; + when Iir_Kind_Association_Element_Subprogram => + -- Replace the interface subprogram by the subprogram. + declare + Inter_Subprg : constant Iir := + Get_Association_Interface (Assoc, Inter); + Actual_Subprg : constant Iir := + Get_Named_Entity (Get_Actual (Assoc)); + begin + Set_Instance (Get_Origin (Inter_Subprg), Actual_Subprg); + end; + when others => + Error_Kind ("instantiate_generic_map", Assoc); + end case; + end Instantiate_Generic_Map; + procedure Instantiate_Generic_Map_Chain (Inst : Iir; Pkg : Iir) is pragma Unreferenced (Pkg); @@ -936,98 +1036,7 @@ package body Vhdl.Sem_Inst is Assoc := Get_Generic_Map_Aspect_Chain (Inst); Inter := Get_Generic_Chain (Inst); while Is_Valid (Assoc) loop - -- Replace formal reference to the instance. - -- Cf Get_association_Interface - declare - Formal : Iir; - begin - Formal := Get_Formal (Assoc); - if Is_Valid (Formal) then - loop - case Get_Kind (Formal) is - when Iir_Kind_Simple_Name - | Iir_Kind_Operator_Symbol => - Set_Named_Entity - (Formal, Get_Instance (Get_Named_Entity (Formal))); - exit; - when Iir_Kind_Slice_Name - | Iir_Kind_Indexed_Name - | Iir_Kind_Selected_Element => - Formal := Get_Prefix (Formal); - when others => - Error_Kind ("instantiate_generic_map_chain", Formal); - end case; - end loop; - end if; - end; - - case Get_Kind (Assoc) is - when Iir_Kind_Association_Element_By_Expression - | Iir_Kind_Association_Element_By_Individual - | Iir_Kind_Association_Element_Open => - -- If the type of the formal is an interface type also - -- associated by this map, change the type of the formal - -- to the associated type. - declare - Assoc_Formal : constant Iir := - Get_Association_Interface (Assoc, Inter); - Formal_Type : constant Iir := Get_Type (Assoc_Formal); - Formal_Orig : Iir; - begin - if Get_Kind (Formal_Type) - = Iir_Kind_Interface_Type_Definition - then - -- Type of the formal is an interface type. - -- Check if the interface type was declared in the same - -- interface list: must have the same parent. - Formal_Orig := Get_Origin (Assoc_Formal); - if Get_Parent (Get_Type_Declarator (Formal_Type)) - = Get_Parent (Formal_Orig) - then - Set_Type (Assoc_Formal, Get_Instance (Formal_Type)); - end if; - end if; - end; - when Iir_Kind_Association_Element_Package => - declare - Sub_Inst : constant Iir := - Get_Named_Entity (Get_Actual (Assoc)); - Sub_Pkg_Inter : constant Iir := - Get_Association_Interface (Assoc, Inter); - Sub_Pkg : constant Iir := Get_Origin (Sub_Pkg_Inter); - begin - -- Replace references of interface package to references - -- to the actual package. - Set_Instance (Sub_Pkg, Sub_Inst); - Set_Instance_On_Chain (Get_Generic_Chain (Sub_Pkg), - Get_Generic_Chain (Sub_Inst)); - Set_Instance_On_Chain (Get_Declaration_Chain (Sub_Pkg), - Get_Declaration_Chain (Sub_Inst)); - end; - when Iir_Kind_Association_Element_Type => - -- Replace the incomplete interface type by the actual subtype - -- indication. - declare - Assoc_Inter : constant Iir := - Get_Association_Interface (Assoc, Inter); - Inter_Type_Def : constant Iir := Get_Type (Assoc_Inter); - Actual_Type : constant Iir := Get_Actual_Type (Assoc); - begin - Set_Instance (Inter_Type_Def, Actual_Type); - end; - when Iir_Kind_Association_Element_Subprogram => - -- Replace the interface subprogram by the subprogram. - declare - Inter_Subprg : constant Iir := - Get_Association_Interface (Assoc, Inter); - Actual_Subprg : constant Iir := - Get_Named_Entity (Get_Actual (Assoc)); - begin - Set_Instance (Get_Origin (Inter_Subprg), Actual_Subprg); - end; - when others => - Error_Kind ("instantiate_generic_map_chain", Assoc); - end case; + Instantiate_Generic_Map (Assoc, Inter); Next_Association_Interface (Assoc, Inter); end loop; end Instantiate_Generic_Map_Chain; diff --git a/src/vhdl/vhdl-utils.adb b/src/vhdl/vhdl-utils.adb index fc97ba185..8e9d5af90 100644 --- a/src/vhdl/vhdl-utils.adb +++ b/src/vhdl/vhdl-utils.adb @@ -597,17 +597,27 @@ package body Vhdl.Utils is procedure Next_Association_Interface (Assoc : in out Iir; Inter : in out Iir) is - Formal : constant Iir := Get_Formal (Assoc); + Formal : Iir; begin -- In canon, open association can be inserted after an association by -- name. So do not assume there is no association by position after -- association by name. + Assoc := Get_Chain (Assoc); + if Assoc = Null_Iir then + -- End of the chain + Inter := Null_Iir; + return; + end if; + + Formal := Get_Formal (Assoc); if Is_Valid (Formal) then - Inter := Get_Chain (Get_Interface_Of_Formal (Formal)); + Inter := Get_Interface_Of_Formal (Formal); else Inter := Get_Chain (Inter); end if; - Assoc := Get_Chain (Assoc); + + -- If INTER is null, this is an extra association. Should it be + -- skipped here ? Or add a _Safe variant ? end Next_Association_Interface; function Get_Association_Formal (Assoc : Iir; Inter : Iir) return Iir |