diff options
author | Andre Vehreschild <vehre@gcc.gnu.org> | 2016-10-01 16:00:57 +0200 |
---|---|---|
committer | Andre Vehreschild <vehre@gcc.gnu.org> | 2016-10-01 16:00:57 +0200 |
commit | 0f0565b1438c82118f1f31f6880c509c472c3bf5 (patch) | |
tree | eff176f1e251fa98b5827cd362cc3acbcca23c7a /libgfortran/caf/single.c | |
parent | eb647b80ba1a0ab2d9b879cbfdd08cd6805e75c3 (diff) | |
download | gcc-0f0565b1438c82118f1f31f6880c509c472c3bf5.zip gcc-0f0565b1438c82118f1f31f6880c509c472c3bf5.tar.gz gcc-0f0565b1438c82118f1f31f6880c509c472c3bf5.tar.bz2 |
re PR libfortran/77663 (libgfortran/caf/single.c: three minor problems and a lost token)
gcc/testsuite/ChangeLog:
2016-10-01 Andre Vehreschild <vehre@gcc.gnu.org>
PR fortran/77663
* gfortran.dg/coarray_send_by_ref_1.f08: New test.
libgfortran/ChangeLog:
2016-10-01 Andre Vehreschild <vehre@gcc.gnu.org>
PR fortran/77663
* caf/single.c (caf_internal_error): Fix not terminating va-list.
(_gfortran_caf_register): Free memory also when other allocs failed.
(_gfortran_caf_get_by_ref): Fixed style.
(send_by_ref): Token is now stored at the correct position preventing
inaccessible tokens, memory loss and possibly crashes.
From-SVN: r240695
Diffstat (limited to 'libgfortran/caf/single.c')
-rw-r--r-- | libgfortran/caf/single.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/libgfortran/caf/single.c b/libgfortran/caf/single.c index c472446..00b7120 100644 --- a/libgfortran/caf/single.c +++ b/libgfortran/caf/single.c @@ -87,6 +87,7 @@ caf_internal_error (const char *msg, int *stat, char *errmsg, if ((size_t)errmsg_len > len) memset (&errmsg[len], ' ', errmsg_len - len); } + va_end (args); return; } else @@ -149,6 +150,13 @@ _gfortran_caf_register (size_t size, caf_register_t type, caf_token_t *token, if (unlikely (local == NULL || *token == NULL)) { + /* Freeing the memory conditionally seems pointless, but + caf_internal_error () may return, when a stat is given and then the + memory may be lost. */ + if (local) + free (local); + if (*token) + free (*token); caf_internal_error (alloc_fail_msg, stat, errmsg, errmsg_len); return; } @@ -1465,7 +1473,7 @@ _gfortran_caf_get_by_ref (caf_token_t token, bool array_extent_fixed = false; realloc_needed = realloc_required = GFC_DESCRIPTOR_DATA (dst) == NULL; - assert (!realloc_needed || (realloc_needed && dst_reallocatable)); + assert (!realloc_needed || dst_reallocatable); if (stat) *stat = 0; @@ -1909,14 +1917,14 @@ send_by_ref (caf_reference_t *ref, size_t *i, size_t *src_index, GFC_DESCRIPTOR_DATA (&static_dst) = NULL; GFC_DESCRIPTOR_DTYPE (&static_dst) = GFC_DESCRIPTOR_DTYPE (src); - /* The component may be allocated now, because it is a + /* The component can be allocated now, because it is a scalar. */ - single_token = *(caf_single_token_t*) - (ds + ref->u.c.caf_token_offset); _gfortran_caf_register (ref->item_size, CAF_REGTYPE_COARRAY_ALLOC, - (caf_token_t *)&single_token, + ds + ref->u.c.caf_token_offset, &static_dst, stat, NULL, 0); + single_token = *(caf_single_token_t *) + (ds + ref->u.c.caf_token_offset); /* In case of an error in allocation return. When stat is NULL, then register_component() terminates on error. */ if (stat != NULL && *stat) @@ -2005,15 +2013,12 @@ send_by_ref (caf_reference_t *ref, size_t *i, size_t *src_index, /* The size of the array is given by size. */ _gfortran_caf_register (size * ref->item_size, CAF_REGTYPE_COARRAY_ALLOC, - (void **)&single_token, + ds + ref->u.c.caf_token_offset, dst, stat, NULL, 0); /* In case of an error in allocation return. When stat is NULL, then register_component() terminates on error. */ if (stat != NULL && *stat) return; - /* The memptr, descriptor and the token are set below. */ - *(caf_single_token_t *)(ds + ref->u.c.caf_token_offset) - = single_token; } single_token = *(caf_single_token_t*)(ds + ref->u.c.caf_token_offset); send_by_ref (ref->next, i, src_index, single_token, |