public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug analyzer] -Wanalyser-malloc-leak false positive on gcc 12.1/12.2
@ 2023-02-27 13:38 Martin Georgiev
0 siblings, 0 replies; only message in thread
From: Martin Georgiev @ 2023-02-27 13:38 UTC (permalink / raw)
To: gcc-bugs
[-- Attachment #1: Type: text/plain, Size: 4442 bytes --]
I send this to gcc-help but it would probably be more appropriate.
While compiling a source file with the -fanalyzer option I got a compiler
-Wanalyser-malloc-leak warning. I followed the diagnostic message but
didn't see the problem so I decided to go look at the assembly code.
Compiling the same source file with gcc 11 and gcc trunk generated
identical assembly code but I did not get the error message. Is this a gcc
12 bug or am I missing something?
You can recreate the behavior described above by switching between
different gcc versions on godbolt.org.
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
struct Binary_Tree_Node {
struct Binary_Tree_Node *left;
struct Binary_Tree_Node *right;
struct Binary_Tree_Node *parent;
void *key;
};
typedef struct{
struct Binary_Tree_Node *root;
int (*comp)(const void *, const void *);
void (*key_destr)(void *);
size_t size;
} Binary_Tree;
struct AVL_Node {
struct Binary_Tree_Node node;
int balance;
};
typedef struct {
Binary_Tree tree;
} AVL_Tree;
enum cdsa_err {ERR_OK = 0, ERR_OUT_OF_MEM, ERR_ELEMENT_NOT_FOUND,
ERR_ELEMENT_EXISTS, ERR_TREE_IS_FULL};
__attribute__((nonnull(1), access(read_write, 1), access(read_only, 2)))
extern enum cdsa_err avl_insert(AVL_Tree * const t, void * const key);
extern enum cdsa_err avl_insert(AVL_Tree * const t, void * const key)
{
Binary_Tree * const bt = (Binary_Tree * const)t;
if (bt->size == SIZE_MAX)
return ERR_TREE_IS_FULL;
struct Binary_Tree_Node **bn = &(bt->root);
struct Binary_Tree_Node *parent = NULL;
// Removing this traversal loop which shouldn't have any effect
removes the diagnose.
while (*bn) {
const int res = bt->comp(key, (*bn)->key);
if (!res)
return ERR_ELEMENT_EXISTS;
parent = *bn;
if (res < 0) {
bn = &(*bn)->left;
continue;
}
bn = &(*bn)->right;
}
struct AVL_Node **n = (struct AVL_Node **)bn;
*n = malloc(sizeof(**n));
if (!(*n))
return ERR_OUT_OF_MEM;
(*bn)->key = key;
(*bn)->left = NULL;
(*bn)->right = NULL;
(*bn)->parent = parent;
(*n)->balance = 0;
//balance_insert(t, *n);
++(bt->size);
return ERR_OK;
}
Here is the output:
<source>:60:9: warning: leak of '<unknown>' [CWE-401]
[-Wanalyzer-malloc-leak]
60 | (*bn)->right = NULL;
| ^
'avl_insert': events 1-11
|
| 35 | if (bt->size == SIZE_MAX)
| | ^
| | |
| | (1) following 'false' branch...
|......
| 38 | struct Binary_Tree_Node **bn = &(bt->root);
| | ~~~~~~
| | |
| | (2) ...to here
|......
| 41 | while (*bn) {
| | ~
| | |
| | (3) following 'true' branch...
| 42 | const int res = bt->comp(key, (*bn)->key);
| | ~~~~~
| | |
| | (4) ...to here
| 43 | if (!res)
| | ~
| | |
| | (5) following 'false' branch (when 'res !=
0')...
| 44 | return ERR_ELEMENT_EXISTS;
| 45 | parent = *bn;
| | ~~~~~~
| | |
| | (6) ...to here
|......
| 54 | *n = malloc(sizeof(**n));
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (7) allocated here
| 55 | if (!(*n))
| | ~
| | |
| | (8) assuming 'malloc(40)' is non-NULL
| | (9) following 'false' branch...
|......
| 58 | (*bn)->key = key;
| | ~
| | |
| | (10) ...to here
| 59 | (*bn)->left = NULL;
| 60 | (*bn)->right = NULL;
| | ~
| | |
| | (11) '<unknown>' leaks here; was allocated at (7)
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-02-27 13:39 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-27 13:38 [Bug analyzer] -Wanalyser-malloc-leak false positive on gcc 12.1/12.2 Martin Georgiev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).