https://gcc.gnu.org/g:05c76637481870f2c3b3c970f0a16adad1652143

commit r17-414-g05c76637481870f2c3b3c970f0a16adad1652143
Author: Harald Anlauf <[email protected]>
Date:   Fri May 8 21:45:31 2026 +0200

    libfortran: fix static analyser cppcheck warning in free_format_data 
[PR125087]
    
    The static analyser cppcheck reported a pointless assignment in function
    free_format_data.  The intent of the assignment was to finally nullify the
    pointer to allocated format data after memory has been freed.  Since C does
    not support references, add a level of indirection to the function argument
    so that the dereferenced argument can be nullified.
    
            PR libfortran/125087
    
    libgfortran/ChangeLog:
    
            * io/format.c (free_format_data): Change argument from pointer to
            format_data to pointer to pointer of object.
            (free_format_hash_table): Adjust argument passed to
            free_format_data.
            (save_parsed_format): Likewise.
            * io/format.h (free_format_data): Adjust prototype.
            * io/transfer.c (st_read_done_worker): Adjust argument passed to
            free_format_data.
            (st_write_done_worker): Likewise.

Diff:
---
 libgfortran/io/format.c   | 16 ++++++++--------
 libgfortran/io/format.h   |  2 +-
 libgfortran/io/transfer.c |  4 ++--
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c
index 2b3ee0b2fbf6..899a0b50f95c 100644
--- a/libgfortran/io/format.c
+++ b/libgfortran/io/format.c
@@ -65,7 +65,7 @@ free_format_hash_table (gfc_unit *u)
     {
       if (u->format_hash_table[i].hashed_fmt != NULL)
        {
-         free_format_data (u->format_hash_table[i].hashed_fmt);
+         free_format_data (&u->format_hash_table[i].hashed_fmt);
          free (u->format_hash_table[i].key);
        }
       u->format_hash_table[i].key = NULL;
@@ -143,7 +143,7 @@ save_parsed_format (st_parameter_dt *dtp)
   /* Index into the hash table.  We are simply replacing whatever is there
      relying on probability.  */
   if (u->format_hash_table[hash].hashed_fmt != NULL)
-    free_format_data (u->format_hash_table[hash].hashed_fmt);
+    free_format_data (&u->format_hash_table[hash].hashed_fmt);
   u->format_hash_table[hash].hashed_fmt = NULL;
 
   free (u->format_hash_table[hash].key);
@@ -258,16 +258,16 @@ free_format (st_parameter_dt *dtp)
 /* free_format_data()-- Free all allocated format data.  */
 
 void
-free_format_data (format_data *fmt)
+free_format_data (format_data **fmt)
 {
   fnode_array *fa, *fa_next;
   fnode *fnp;
 
-  if (fmt == NULL)
+  if (fmt == NULL || *fmt == NULL)
     return;
 
   /* Free vlist descriptors in the fnode_array if one was allocated.  */
-  for (fnp = fmt->array.array; fnp < &fmt->array.array[FARRAY_SIZE] &&
+  for (fnp = (*fmt)->array.array; fnp < &(*fmt)->array.array[FARRAY_SIZE] &&
        fnp->format != FMT_NONE; fnp++)
     if (fnp->format == FMT_DT)
        {
@@ -275,14 +275,14 @@ free_format_data (format_data *fmt)
          free (fnp->u.udf.vlist);
        }
 
-  for (fa = fmt->array.next; fa; fa = fa_next)
+  for (fa = (*fmt)->array.next; fa; fa = fa_next)
     {
       fa_next = fa->next;
       free (fa);
     }
 
-  free (fmt);
-  fmt = NULL;
+  free (*fmt);
+  *fmt = NULL;
 }
 
 
diff --git a/libgfortran/io/format.h b/libgfortran/io/format.h
index ff3acf0e7b24..5ab30bf6c829 100644
--- a/libgfortran/io/format.h
+++ b/libgfortran/io/format.h
@@ -122,7 +122,7 @@ internal_proto(unget_format);
 extern void format_error (st_parameter_dt *, const fnode *, const char *);
 internal_proto(format_error);
 
-extern void free_format_data (struct format_data *);
+extern void free_format_data (struct format_data **);
 internal_proto(free_format_data);
 
 extern void free_format (st_parameter_dt *);
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index 7e6795e70f7e..c81993e4635e 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -4668,7 +4668,7 @@ st_read_done_worker (st_parameter_dt *dtp, bool unlock)
        }
       if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved)
        {
-         free_format_data (dtp->u.p.fmt);
+         free_format_data (&dtp->u.p.fmt);
          free_format (dtp);
        }
     }
@@ -4764,7 +4764,7 @@ st_write_done_worker (st_parameter_dt *dtp, bool unlock)
        }
       if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved)
        {
-         free_format_data (dtp->u.p.fmt);
+         free_format_data (&dtp->u.p.fmt);
          free_format (dtp);
        }
     }

Reply via email to