[Bug analyzer/103217] New: analyzer false positive on leak warning when using indirect strdup
npfhrotynz-ptnqh.myvf at noclue dot notk.org
gcc-bugzilla@gcc.gnu.org
Sat Nov 13 00:30:36 GMT 2021
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103217
Bug ID: 103217
Summary: analyzer false positive on leak warning when using
indirect strdup
Product: gcc
Version: 11.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: analyzer
Assignee: dmalcolm at gcc dot gnu.org
Reporter: npfhrotynz-ptnqh.myvf at noclue dot notk.org
Target Milestone: ---
Inlining both the reproducer and fanalyzer warning as they are small enough:
----------
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
char *xstrdup(const char *src) {
char *val = strdup(src);
if (!val)
abort();
return val;
}
int main(int argc, char *argv[]) {
char *one = NULL, *two = NULL;
int rc;
while ((rc = getopt(argc, argv, "a:b:")) != -1) {
switch (rc) {
case 'a':
free(one);
one = xstrdup(optarg);
break;
case 'b':
free(two);
two = xstrdup(optarg);
break;
}
}
free(one);
free(two);
return 0;
}
----------
----------
$ gcc -fanalyzer -o t t.c
t.c: In function ‘main’:
cc1: warning: leak of ‘val’ [CWE-401] [-Wanalyzer-malloc-leak]
‘main’: events 1-4
|
|t.c:13:5:
| 13 | int main(int argc, char *argv[]) {
| | ^~~~
| | |
| | (1) entry to ‘main’
|......
| 17 | while ((rc = getopt(argc, argv, "a:b:")) != -1) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (2) following
‘true’ branch (when ‘rc != -1’)...
| 18 | switch (rc) {
| | ~~~~~~
| | |
| | (3) ...to here
|......
| 25 | two = xstrdup(optarg);
| | ~~~~~~~~~~~~~~~
| | |
| | (4) calling ‘xstrdup’ from ‘main’
|
+--> ‘xstrdup’: events 5-9
|
| 6 | char *xstrdup(const char *src) {
| | ^~~~~~~
| | |
| | (5) entry to ‘xstrdup’
| 7 | char *val = strdup(src);
| | ~~~~~~~~~~~
| | |
| | (6) allocated here
| 8 | if (!val)
| | ~
| | |
| | (7) assuming ‘val’ is non-NULL
| | (8) following ‘false’ branch (when ‘val’ is
non-NULL)...
| 9 | abort();
| 10 | return val;
| | ~~~
| | |
| | (9) ...to here
|
<------+
|
‘main’: event 10
|
| 25 | two = xstrdup(optarg);
| | ^~~~~~~~~~~~~~~
| | |
| | (10) returning to ‘main’ from
‘xstrdup’
|
‘main’: event 11
|
|cc1:
| (11): ‘val’ leaks here; was allocated at (6)
|
----------
As far as I see the conditions seem to be:
- there have to be at least two cases and two variables, adding more than two
cases leave the error only on second one; interverting the two makes the error
stay on 2nd. Similarly, using the same variable in both cases makes the error
go away.
- it has to be strdup, replacing strdup with malloc makes the error go away.
- it has to be indirected, calling strdup() directly in main (with the same
check/abort) makes the error go away. explicit "inline" attribute does not
change behaviour.
- it doesn't have to be getopt, but there has to be a function call e.g.
replacing getopt() with a locally defined iteration function keeps the error,
but checking argc/argv directly in the loop makes the error disappear
What's also interesting is the event 11 and "(11): ‘val’ leaks here" that
points to... nothing at all? There's no line number or any code quoted to refer
to. I'm a bit at a loss as to what this could mean, exiting from main? where?
More information about the Gcc-bugs
mailing list