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] |
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] |