This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, libgfortran] PR 40330 Fix use of saved format strings


Hi,

the attached patch fixes PR 40330. The problem was that for the saved
format strings we were just keeping pointer to the strings that reside
in the st_parameter_dt structure. However, this lives on the stack so
once it goes out of scope the cached entries became invalid. Fixed by
using heap storage.

Regtested on x86_64-unknown-linux-gnu, Ok for trunk and 4.4?

-- 
Janne Blomqvist

Attachment: ChangeLog
Description: Binary data

diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c
index a1ec43c..bd40419 100644
--- a/libgfortran/io/format.c
+++ b/libgfortran/io/format.c
@@ -87,7 +87,12 @@ free_format_hash_table (gfc_unit *u)
   for (i = 0; i < FORMAT_HASH_SIZE; i++)
     {
       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_mem (u->format_hash_table[i].key);
+	}
+      u->format_hash_table[i].key = NULL;
+      u->format_hash_table[i].key_len = 0;      
       u->format_hash_table[i].hashed_fmt = NULL;
     }
 }
@@ -164,7 +169,10 @@ save_parsed_format (st_parameter_dt *dtp)
     free_format_data (u->format_hash_table[hash].hashed_fmt);
   u->format_hash_table[hash].hashed_fmt = NULL;
 
-  u->format_hash_table[hash].key = dtp->format;
+  u->format_hash_table[hash].key 
+    = gfc_realloc (u->format_hash_table[hash].key, dtp->format_len);
+  memcpy (u->format_hash_table[hash].key, dtp->format, dtp->format_len);
+
   u->format_hash_table[hash].key_len = dtp->format_len;
   u->format_hash_table[hash].hashed_fmt = dtp->u.p.fmt;
 }
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index 3591fa9..b075ac0 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -681,6 +681,9 @@ internal_proto(set_fpu);
 extern void *get_mem (size_t) __attribute__ ((malloc));
 internal_proto(get_mem);
 
+extern void *gfc_realloc (void *, size_t);
+internal_proto(gfc_realloc);
+
 extern void free_mem (void *);
 internal_proto(free_mem);
 
diff --git a/libgfortran/runtime/memory.c b/libgfortran/runtime/memory.c
index d1b57f6..c7e49d3 100644
--- a/libgfortran/runtime/memory.c
+++ b/libgfortran/runtime/memory.c
@@ -48,6 +48,17 @@ get_mem (size_t n)
   return p;
 }
 
+/* Safe realloc that aborts the program on failure. */
+
+void *
+gfc_realloc (void * ptr, size_t size)
+{
+  ptr = realloc (ptr, size);
+  if (ptr == NULL)
+    os_error("Memory re-allocation failed");
+  return ptr;
+}
+
 
 void
 free_mem (void *p)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]