This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libobjc/11904] New: Problem in sarray_free() function.
- From: "sergant at orcsoftware dot spb dot ru" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 13 Aug 2003 09:18:34 -0000
- Subject: [Bug libobjc/11904] New: Problem in sarray_free() function.
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11904
Summary: Problem in sarray_free() function.
Product: gcc
Version: tree-ssa
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: libobjc
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: sergant at orcsoftware dot spb dot ru
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: i686-pc-mingw32
GCC host triplet: i686-pc-mingw32
GCC target triplet: i686-pc-mingw32
sarray_lazy_copy() function creates an array with reference to the original
array and pointers to the original array's buckets. sarray_free() function
looks like:
void
sarray_free(struct sarray* array) {
... some code ...
if((array->is_copy_of) && ((array->is_copy_of->ref_count - 1) == 0))
sarray_free(array->is_copy_of);
/* Free all entries that do not point to empty_bucket */
for(counter = 0; counter <= old_max_index; counter++ ) {
#ifdef OBJC_SPARSE3
struct sindex* idx = old_indices[counter];
if((idx != array->empty_index) &&
(idx->version.version == array->version.version)) {
int c2;
for(c2=0; c2<INDEX_SIZE; c2++) {
struct sbucket* bkt = idx->buckets[c2];
if((bkt != array->empty_bucket) &&
(bkt->version.version == array->version.version))
{
sarray_free_garbage(bkt);
nbuckets -= 1;
}
}
sarray_free_garbage(idx);
nindices -= 1;
}
#else /* OBJC_SPARSE2 */
struct sbucket* bkt = array->buckets[counter];
if ((bkt != array->empty_bucket) &&
(bkt->version.version == array->version.version))
{
sarray_free_garbage(bkt);
nbuckets -= 1;
}
#endif
}
... some code ...
}
In case, when array is a lazy copy of some other array it calls sarray_free()
for the oroginal array, and then deallocates it's own created buckets. Array
can have some pointers to the original array's buckets that are already
deallocated, and thus sometimes we have access to the freed memory in block of
code:
struct sbucket* bkt = array->buckets[counter];
if ((bkt != array->empty_bucket) &&
(bkt->version.version == array->version.version))
{
sarray_free_garbage(bkt);
nbuckets -= 1;
}
at line '(bkt->version.version == array->version.version)' (memory pointed
by 'bkt' can be already freed).
The possible solution of this problem is to move deallocation of (array-
>is_copy_of) array to the end of function sarray_free().