* -fanalyzer false positive on gcc 12.1 and gcc 12.2
@ 2023-02-26 17:52 Martin Georgiev
0 siblings, 0 replies; only message in thread
From: Martin Georgiev @ 2023-02-26 17:52 UTC (permalink / raw)
To: gcc-help
[-- Attachment #1: Type: text/plain, Size: 4191 bytes --]
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>: In function 'avl_insert':
<source>:58:15: warning: leak of '<unknown>' [CWE-401]
[-Wanalyzer-malloc-leak]
58 | if (!(*n))
| ~^~~
'avl_insert': events 1-8
|
| 38 | if (bt->size == SIZE_MAX)
| | ^
| | |
| | (1) following 'false' branch...
|......
| 41 | struct Binary_Tree_Node **bn = &(bt->root);
| | ~~
| | |
| | (2) ...to here
|......
| 44 | while (*bn) {
| | ~
| | |
| | (3) following 'true' branch...
| 45 | const int res = bt->comp(key, (*bn)->key);
| | ~~~~~~~~
| | |
| | (4) ...to here
| 46 | if (!res)
| | ~
| | |
| | (5) following 'false' branch (when 'res !=
0')...
| 47 | return ERR_ELEMENT_EXISTS;
| 48 | parent = *bn;
| | ~~~~~~~~~~~~
| | |
| | (6) ...to here
|......
| 57 | *n = malloc(sizeof(**n));
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (7) allocated here
| 58 | if (!(*n))
| | ~~~~
| | |
| | (8) '<unknown>' leaks here; was allocated at (7)
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-02-26 17:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-26 17:52 -fanalyzer false positive on gcc 12.1 and gcc 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).