Statically identified memory leaks in libiberty
David Heine
dlheine@suif.Stanford.EDU
Thu Apr 3 06:23:00 GMT 2003
I've identified a number of potential memory leaks in code
in libiberty using a static leak detection tool built for my research.
I originally posted this patch to the binutils mailing list
and was told that it belongs here instead.
2003-04-02 David Heine <dlheine@suif.stanford.edu>
* cp-demangle.c (string_list_new): Fix memory leaks.
(demangling_new): Likewise.
(demangle_template_args): Likewise.
(cp_demangle): Likewise.
(cp_demangle_type): Likewise.
(java_demangle_v3): Likewise.
* partition.c (partition_print): Fix a memory leak.
* make-relative-prefix.c (make_relative_prefix): Fix memory leaks.
Index: cp-demangle.c
===================================================================
RCS file: /cvs/src/src/libiberty/cp-demangle.c,v
retrieving revision 1.27
diff -c -r1.27 cp-demangle.c
*** cp-demangle.c 20 Sep 2002 13:45:20 -0000 1.27
--- cp-demangle.c 3 Apr 2003 06:19:38 -0000
***************
*** 225,230 ****
--- 225,242 ----
} \
while (0)
+ #define CLEANUP_IF_ERROR(EXPR) \
+ do \
+ { \
+ status_t s = EXPR; \
+ if (!STATUS_NO_ERROR (s)) \
+ { \
+ error_status = s; \
+ goto err_return; \
+ } \
+ } \
+ while (0)
+
static status_t int_to_dyn_string
PARAMS ((int, dyn_string_t));
static string_list_t string_list_new
***************
*** 422,428 ****
if (s == NULL)
return NULL;
if (!dyn_string_init ((dyn_string_t) s, length))
! return NULL;
return s;
}
--- 434,443 ----
if (s == NULL)
return NULL;
if (!dyn_string_init ((dyn_string_t) s, length))
! {
! free (s);
! return NULL;
! }
return s;
}
***************
*** 826,837 ****
dm->template_arg_lists = NULL;
dm->last_source_name = dyn_string_new (0);
if (dm->last_source_name == NULL)
! return NULL;
dm->substitutions = (struct substitution_def *)
malloc (dm->substitutions_allocated * sizeof (struct substitution_def));
if (dm->substitutions == NULL)
{
dyn_string_delete (dm->last_source_name);
return NULL;
}
dm->style = style;
--- 841,856 ----
dm->template_arg_lists = NULL;
dm->last_source_name = dyn_string_new (0);
if (dm->last_source_name == NULL)
! {
! free (dm);
! return NULL;
! }
dm->substitutions = (struct substitution_def *)
malloc (dm->substitutions_allocated * sizeof (struct substitution_def));
if (dm->substitutions == NULL)
{
dyn_string_delete (dm->last_source_name);
+ free (dm);
return NULL;
}
dm->style = style;
***************
*** 2986,2991 ****
--- 3005,3011 ----
int first = 1;
dyn_string_t old_last_source_name;
template_arg_list_t arg_list = template_arg_list_new ();
+ status_t error_status;
if (arg_list == NULL)
return STATUS_ALLOCATION_FAILED;
***************
*** 2997,3006 ****
DEMANGLE_TRACE ("template-args", dm);
if (dm->last_source_name == NULL)
! return STATUS_ALLOCATION_FAILED;
! RETURN_IF_ERROR (demangle_char (dm, 'I'));
! RETURN_IF_ERROR (result_open_template_list (dm));
do
{
string_list_t arg;
--- 3017,3029 ----
DEMANGLE_TRACE ("template-args", dm);
if (dm->last_source_name == NULL)
! {
! template_arg_list_delete (arg_list);
! return STATUS_ALLOCATION_FAILED;
! }
! CLEANUP_IF_ERROR (demangle_char (dm, 'I'));
! CLEANUP_IF_ERROR (result_open_template_list (dm));
do
{
string_list_t arg;
***************
*** 3008,3029 ****
if (first)
first = 0;
else
! RETURN_IF_ERROR (result_add (dm, ", "));
/* Capture the template arg. */
! RETURN_IF_ERROR (result_push (dm));
! RETURN_IF_ERROR (demangle_template_arg (dm));
arg = result_pop (dm);
/* Emit it in the demangled name. */
! RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
/* Save it for use in expanding <template-param>s. */
template_arg_list_add_arg (arg_list, arg);
}
while (peek_char (dm) != 'E');
/* Append the '>'. */
! RETURN_IF_ERROR (result_close_template_list (dm));
/* Consume the 'E'. */
advance_char (dm);
--- 3031,3052 ----
if (first)
first = 0;
else
! CLEANUP_IF_ERROR (result_add (dm, ", "));
/* Capture the template arg. */
! CLEANUP_IF_ERROR (result_push (dm));
! CLEANUP_IF_ERROR (demangle_template_arg (dm));
arg = result_pop (dm);
/* Emit it in the demangled name. */
! CLEANUP_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
/* Save it for use in expanding <template-param>s. */
template_arg_list_add_arg (arg_list, arg);
}
while (peek_char (dm) != 'E');
/* Append the '>'. */
! CLEANUP_IF_ERROR (result_close_template_list (dm));
/* Consume the 'E'. */
advance_char (dm);
***************
*** 3038,3043 ****
--- 3061,3072 ----
push_template_arg_list (dm, arg_list);
return STATUS_OK;
+
+ err_return:
+ if (arg_list != NULL)
+ template_arg_list_delete(arg_list);
+ return error_status;
+
}
/* This function, which does not correspond to a production in the
***************
*** 3578,3584 ****
{
dyn_string_t demangled = (dyn_string_t) result_pop (dm);
if (!dyn_string_copy (result, demangled))
! return STATUS_ALLOCATION_FAILED;
dyn_string_delete (demangled);
}
--- 3607,3617 ----
{
dyn_string_t demangled = (dyn_string_t) result_pop (dm);
if (!dyn_string_copy (result, demangled))
! {
! dyn_string_delete (demangled);
! demangling_delete (dm);
! return STATUS_ALLOCATION_FAILED;
! }
dyn_string_delete (demangled);
}
***************
*** 3628,3634 ****
it into RESULT. */
dyn_string_t demangled = (dyn_string_t) result_pop (dm);
if (!dyn_string_copy (result, demangled))
! return STATUS_ALLOCATION_FAILED;
dyn_string_delete (demangled);
}
--- 3661,3671 ----
it into RESULT. */
dyn_string_t demangled = (dyn_string_t) result_pop (dm);
if (!dyn_string_copy (result, demangled))
! {
! dyn_string_delete (demangled);
! demangling_delete (dm);
! return STATUS_ALLOCATION_FAILED;
! }
dyn_string_delete (demangled);
}
Index: make-relative-prefix.c
===================================================================
RCS file: /cvs/src/src/libiberty/make-relative-prefix.c,v
retrieving revision 1.4
diff -c -r1.4 make-relative-prefix.c
*** make-relative-prefix.c 20 Feb 2003 22:13:32 -0000 1.4
--- make-relative-prefix.c 3 Apr 2003 06:19:38 -0000
***************
*** 301,310 ****
return NULL;
prog_dirs = split_directories (full_progname, &prog_num);
- bin_dirs = split_directories (bin_prefix, &bin_num);
free (full_progname);
! if (bin_dirs == NULL || prog_dirs == NULL)
return NULL;
/* Remove the program name from comparison of directory names. */
prog_num--;
--- 301,315 ----
return NULL;
prog_dirs = split_directories (full_progname, &prog_num);
free (full_progname);
! if (prog_dirs == NULL)
return NULL;
+ bin_dirs = split_directories (bin_prefix, &bin_num);
+ if (bin_dirs == NULL)
+ {
+ free_split_directories (prog_dirs);
+ return NULL;
+ }
/* Remove the program name from comparison of directory names. */
prog_num--;
***************
*** 367,373 ****
ret = (char *) malloc (needed_len);
if (ret == NULL)
! return NULL;
/* Build up the pathnames in argv[0]. */
*ret = '\0';
--- 372,383 ----
ret = (char *) malloc (needed_len);
if (ret == NULL)
! {
! free_split_directories (prog_dirs);
! free_split_directories (bin_dirs);
! free_split_directories (prefix_dirs);
! return NULL;
! }
/* Build up the pathnames in argv[0]. */
*ret = '\0';
Index: partition.c
===================================================================
RCS file: /cvs/src/src/libiberty/partition.c,v
retrieving revision 1.4
diff -c -r1.4 partition.c
*** partition.c 16 May 2001 21:04:30 -0000 1.4
--- partition.c 3 Apr 2003 06:19:38 -0000
***************
*** 186,191 ****
--- 186,192 ----
}
fputc (']', fp);
+ free (class_elements);
free (done);
}
More information about the Gcc-patches
mailing list