Fix some on error memory leaks in vvp.

This patch modifies the vvp main code to cleanup if there was an
error compiling the input file. There are still a few issues, but
this takes care of most of them.
This commit is contained in:
Cary R 2010-06-14 19:29:38 -07:00 committed by Stephen Williams
parent 07ee2e7dff
commit 3868334f5c
2 changed files with 54 additions and 30 deletions

View File

@ -192,6 +192,41 @@ void set_delay_selection(const char* sel)
delete[] sel;
}
static void final_cleanup()
{
/*
* We only need to cleanup the memory if we are checking with valgrind.
*/
#ifdef CHECK_WITH_VALGRIND
/* Clean up the file name table. */
for (vector<const char*>::iterator cur = file_names.begin();
cur != file_names.end() ; cur++) {
delete[] *cur;
}
/* Clear the static result buffer. */
(void)need_result_buf(0, RBUF_DEL);
codespace_delete();
root_table_delete();
def_table_delete();
vpi_mcd_delete();
dec_str_delete();
modpath_delete();
vpi_handle_delete();
udp_defns_delete();
island_delete();
signal_pool_delete();
vvp_net_pool_delete();
ufunc_pool_delete();
#endif
/*
* Unload the VPI modules. This is essential for MinGW, to ensure
* dump files are flushed before the main process terminates, as
* the DLL termination code is called after all remaining open
* files are automatically closed.
*/
load_module_delete();
}
unsigned module_cnt = 0;
const char*module_tab[64];
@ -385,6 +420,7 @@ int main(int argc, char*argv[])
if (compile_errors > 0) {
vpi_mcd_printf(1, "%s: Program not runnable, %u errors.\n",
design_path, compile_errors);
final_cleanup();
return compile_errors;
}
@ -463,36 +499,7 @@ int main(int argc, char*argv[])
count_gen_events, count_gen_pool());
}
/*
* We only need to cleanup the memory if we are checking with valgrind.
*/
#ifdef CHECK_WITH_VALGRIND
/* Clean up the memory. */
for (vector<const char*>::iterator cur = file_names.begin();
cur != file_names.end() ; cur++) {
delete[] *cur;
}
(void)need_result_buf(0, RBUF_DEL);
codespace_delete();
root_table_delete();
def_table_delete();
vpi_mcd_delete();
dec_str_delete();
modpath_delete();
vpi_handle_delete();
udp_defns_delete();
island_delete();
signal_pool_delete();
vvp_net_pool_delete();
ufunc_pool_delete();
#endif
/*
* Unload the VPI modules. This is essential for MinGW, to ensure
* dump files are flushed before the main process terminates, as
* the DLL termination code is called after all remaining open
* files are automatically closed.
*/
load_module_delete();
final_cleanup();
return vvp_return_value;
}

View File

@ -713,6 +713,18 @@ void print_vpi_call_errors()
free(vpi_call_error_lst);
}
static void cleanup_vpi_call_args(unsigned argc, vpiHandle*argv)
{
#ifdef CHECK_WITH_VALGRIND
if (argc) {
struct __vpiSysTaskCall*obj = new struct __vpiSysTaskCall;
obj->nargs = argc;
obj->args = argv;
vpi_call_delete(&obj->base);
}
#endif
}
/*
* A vpi_call is actually built up into a vpiSysTaskCall VPI object
* that refers back to the vpiUserSystf VPI object that is the
@ -736,6 +748,7 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
struct __vpiUserSystf*defn = vpip_find_systf(name);
if (defn == 0) {
add_vpi_call_error(VPI_CALL_NO_DEF, name, file_idx, lineno);
cleanup_vpi_call_args(argc, argv);
return 0;
}
@ -744,6 +757,7 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
if (vwid != 0 || fnet != 0) {
add_vpi_call_error(VPI_CALL_TASK_AS_FUNC, name, file_idx,
lineno);
cleanup_vpi_call_args(argc, argv);
return 0;
}
assert(vbit == 0);
@ -754,6 +768,7 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
if (func_as_task_err) {
add_vpi_call_error(VPI_CALL_FUNC_AS_TASK,
name, file_idx, lineno);
cleanup_vpi_call_args(argc, argv);
return 0;
} else if (func_as_task_warn) {
add_vpi_call_error(VPI_CALL_FUNC_AS_TASK_WARN,
@ -818,6 +833,8 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
void vpi_call_delete(vpiHandle item)
{
struct __vpiSysTaskCall*obj = (struct __vpiSysTaskCall *) item;
/* The object can be NULL if there was an error. */
if (!obj) return;
for (unsigned arg = 0; arg < obj->nargs; arg += 1) {
switch (obj->args[arg]->vpi_type->type_code) {
case vpiConstant: