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