Dear all, as the subject already says: this patch fixes a static analyser cppcheck warning which pointed to a minor issue. After freeing memory, the intention was to nullify the pointer pointing to the object, but the (C) code did not do what the programmer wanted...
Pushed to mainline after regtesting on x86_64-pc-linux-gnu and getting an OK from both Jerry and David (who reported the issue) in the PR. This is now r17-414-g05c76637481870 . Thanks, Harald
From 05c76637481870f2c3b3c970f0a16adad1652143 Mon Sep 17 00:00:00 2001 From: Harald Anlauf <[email protected]> Date: Fri, 8 May 2026 21:45:31 +0200 Subject: [PATCH] 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. --- 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 2b3ee0b2fbf..899a0b50f95 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 ff3acf0e7b2..5ab30bf6c82 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 7e6795e70f7..c81993e4635 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); } } -- 2.51.0
