https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94858
Bug ID: 94858
Summary: False report of memory leak
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: analyzer
Assignee: dmalcolm at gcc dot gnu.org
Reporter: addw at phcomp dot co.uk
Target Milestone: ---
Report of a memory leak - that does not happen.
If malloc()/realloc() fails then td->hs_index is left untouched.
#include
#define FALSE 0
#define TRUE1
#define HASH_EMPTY -1
typedef short hashNx;
typedef struct hashSt {
hashNx* hs_index; // Indicies into table - hashed to find index
int hs_used;// Entries used in hs_index
int hs_slots; // Available slots in hs_index
} hashSt;
voidhashEmpty(hashSt* td);
int hashAlloc(hashSt* td, int slots)
{
hashNx* index;
// Is the index already at least that big ?
if(slots > td->hs_slots) {
// New or reallocate ?
if(td->hs_index != NULL)
index = realloc(td->hs_index, (size_t)slots *
sizeof(hashNx));
else
index = malloc((size_t)slots * sizeof(hashNx));
if(index == NULL)
return(FALSE);
// If we get here malloc()/realloc() worked
td->hs_index = index;
td->hs_slots = slots;
}
hashEmpty(td); // Clear the index
return(TRUE);
}
/* Mark everything in the hash index as empty.
* This is useful if you have deleted something and need to reindex.
* It is OK to call this on a table that has not been initialised.
*/
voidhashEmpty(hashSt* td)
{
hashNx* index;
int slots;
for(slots = td->hs_slots, index = td->hs_index; --slots >= 0; )
*index++ = HASH_EMPTY;
td->hs_used = 0;
}
cc -O2 -Wall -Wno-pointer-sign -Wconversion -fanalyzer -c -o hasha.o hasha.c
In function ‘hashAlloc’:
hasha.c:54:14: warning: leak of ‘index’ [CWE-401] [-Wanalyzer-malloc-leak]
54 | td->hs_used = 0;
| ^~~
‘hashAlloc’: events 1-9
|
| 22 | if(slots > td->hs_slots) {
| |^
| ||
| |(1) following ‘true’ branch...
|..