public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug analyzer/106436] New: -Wanalyzer-null-dereference false positive suggests data corruption in GCC
@ 2022-07-25 16:37 eggert at cs dot ucla.edu
0 siblings, 0 replies; only message in thread
From: eggert at cs dot ucla.edu @ 2022-07-25 16:37 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106436
Bug ID: 106436
Summary: -Wanalyzer-null-dereference false positive suggests
data corruption in GCC
Product: gcc
Version: 12.1.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: analyzer
Assignee: dmalcolm at gcc dot gnu.org
Reporter: eggert at cs dot ucla.edu
Target Milestone: ---
Created attachment 53347
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53347&action=edit
Compile with -O2 -S -fanalyzer (GCC 12 x86-64) to reproduce the bug.
I found this problem when compiling Gnu Tar with GCC 12.1.1 20220507 (Red Hat
12.1.1-1) on x86-64. Compile the attached program t.i with:
gcc -O2 -S -fanalyzer t.i
The output is below. The first diagnostic is a false positive. Attempting to
silence it by inserting "if (!listed_loc) abort ();" before line 13975 causes
unrelated diagnostics to change, suggesting that there's some sort of confusion
in the internal data structure that GCC uses to represent the program.
t.i: In function ‘optloc_eq’:
t.i:12193:8: warning: dereference of NULL ‘a’ [CWE-476]
[-Wanalyzer-null-dereference]
12193 | if (a->source != b->source)
| ~^~~~~~~~
‘main’: events 1-4
|
|14348 | main (int argc, char **argv)
| | ^~~~
| | |
| | (1) entry to ‘main’
|......
|14373 | if (stdopen ())
| | ~
| | |
| | (2) following ‘false’ branch...
|......
|14383 | allocated_archive_names = 10;
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
|......
|14400 | decode_options (argc, argv);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (4) calling ‘decode_options’ from ‘main’
|
+--> ‘decode_options’: events 5-7
|
|13764 | decode_options (int argc, char **argv)
| | ^~~~~~~~~~~~~~
| | |
| | (5) entry to ‘decode_options’
|......
|13767 | struct option_locus loc = { OPTS_COMMAND_LINE, 0,
0, 0 };
| | ~~~
| | |
| | (6) ‘loc.prev’ is NULL
|......
|13890 | parse_default_options (&args);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (7) calling ‘parse_default_options’ from
‘decode_options’
|
+--> ‘parse_default_options’: events 8-10
|
|13721 | parse_default_options (struct tar_args
*args)
| | ^~~~~~~~~~~~~~~~~~~~~
| | |
| | (8) entry to ‘parse_default_options’
|......
|13725 | struct option_locus loc = { OPTS_ENVIRON,
"TAR_OPTIONS", 0, 0 };
| | ~~~
| | |
| | (9) ‘loc.prev’ is NULL
| | (10) ‘loc.prev’ is
NULL
|
<------+
|
‘decode_options’: events 11-20
|
|12176 | return option_class[id];
| | ~~~~~~~~~~~~~~~~
| | |
| | (17) ...to here
| | (18) ‘0’ is NULL
| | (19) ‘0’ is NULL
|......
|13890 | parse_default_options (&args);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (11) returning to ‘decode_options’ from
‘parse_default_options’
|13891 |
|13892 | if (argp_parse (&argp, argc, argv, 0x08, &idx,
&args))
| | ~
| | |
| | (12) following ‘false’ branch...
|13893 | exit (2);
|13894 | if (args.o_option)
| | ~~~~~~~~~~~~~
| | |
| | (13) ...to here
|......
|13970 | if (listed_incremental_option
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (14) following ‘true’ branch...
|13971 | && (0 <= (newer_mtime_option).tv_nsec))
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (15) ...to here
| | (16) following ‘true’ branch...
|......
|13975 | if (optloc_eq (listed_loc, newer_loc))
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (20) calling ‘optloc_eq’ from
‘decode_options’
|
+--> ‘optloc_eq’: events 21-22
|
|12191 | optloc_eq (struct option_locus *a, struct
option_locus *b)
| | ^~~~~~~~~
| | |
| | (21) entry to ‘optloc_eq’
|12192 | {
|12193 | if (a->source != b->source)
| | ~~~~~~~~~
| | |
| | (22) dereference of NULL ‘a’
|
t.i: In function ‘get_date_or_file’:
t.i:12354:23: warning: leak of ‘p’ [CWE-401] [-Wanalyzer-malloc-leak]
12354 | args->textual_date = p;
| ~~~~~~~~~~~~~~~~~~~^~~
‘parse_opt’: events 1-4
|
|12682 | parse_opt (int key, char *arg, struct argp_state *state)
| | ^~~~~~~~~
| | |
| | (1) entry to ‘parse_opt’
|......
|12686 | switch (key)
| | ~~~~~~
| | |
| | (2) following ‘case 152:’ branch...
|......
|12946 | case MTIME_OPTION:
| | ~~~~
| | |
| | (3) ...to here
|12947 | get_date_or_file (args, "--mtime", arg,
&mtime_option);
| |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (4) calling ‘get_date_or_file’ from ‘parse_opt’
|
+--> ‘get_date_or_file’: events 5-13
|
|12303 | get_date_or_file (struct tar_args *args, const char
*rpl_option,
| | ^~~~~~~~~~~~~~~~
| | |
| | (5) entry to ‘get_date_or_file’
|......
|12307 | ((void) (
| | ~~~~~~~~~
|12308 | str
| | ~~~
|12309 | ), 0)
| | ~~~~~
|12310 | != 0
| | ~~~~
|12311 | ||
| | ~~
| | |
| | (6) following ‘false’ branch...
|12312 | ((
| | ~~
|12313 | *str
| | ~~~~
|12314 | ) == '/')
| | ~~~~~~~~~
|12315 |
| |
|12316 | || *str == '.')
| | ~~~~~~~~~~~~~~
| | |
| | (7) ...to here
| | (8) following ‘false’ branch...
|......
|12332 | if (! parse_datetime (ts, str,
| | ~ ~~~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (9) ...to here
| | (10) following ‘true’ branch...
|12333 | ((void *)0)
| | ~~~~~~~~~~~
|12334 | ))
| | ~
|......
|12349 | struct textual_date *p = xmalloc (sizeof (*p));
| | ~~~~~~~~~~~~~~~~~~~~~
| | |
| | (11) ...to here
| | (12) allocated here
|......
|12354 | args->textual_date = p;
| | ~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (13) ‘p’ leaks here; was
allocated at (12)
|
t.i: In function ‘decode_options’:
t.i:13862:35: warning: leak of ‘xstrdup(&buffer)’ [CWE-401]
[-Wanalyzer-malloc-leak]
13862 | opt = find_argp_option (&argp, *letter);
| ^~~~~~~
‘decode_options’: events 1-7
|
|13764 | decode_options (int argc, char **argv)
| | ^~~~~~~~~~~~~~
| | |
| | (1) entry to ‘decode_options’
|......
|13831 | if (argc > 1 && argv[1][0] != '-')
| | ~
| | |
| | (2) following ‘true’ branch...
|......
|13842 | buffer[0] = '-';
| | ~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
|......
|13856 | for (letter = *in++; *letter; letter++)
| | ~
| | |
| | (4) following ‘true’ branch...
|......
|13860 | buffer[1] = *letter;
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (5) ...to here
|13861 | *out++ = xstrdup (buffer);
| | ~~~~~~~~~~~~~~~~
| | |
| | (6) allocated here
|13862 | opt = find_argp_option (&argp, *letter);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (7) calling ‘find_argp_option’ from
‘decode_options’
|
+--> ‘find_argp_option’: events 8-10
|
|13655 | find_argp_option (struct argp *ap, int key)
| | ^~~~~~~~~~~~~~~~
| | |
| | (8) entry to ‘find_argp_option’
|......
|13663 | if (!p && ap->children)
| | ~
| | |
| | (9) following ‘false’ branch (when ‘p’ is
non-NULL)...
|......
|13672 | return p;
| | ~
| | |
| | (10) ...to here
|
<------+
|
‘decode_options’: events 11-17
|
|13856 | for (letter = *in++; *letter; letter++)
| | ~
| | |
| | (14) following ‘true’ branch...
|......
|13860 | buffer[1] = *letter;
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (15) ...to here
|13861 | *out++ = xstrdup (buffer);
| | ~~~~~~~~~~~~~~~~
| | |
| | (16) allocated here
|13862 | opt = find_argp_option (&argp, *letter);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (17) ‘xstrdup(&buffer)’
leaks here; was allocated at (16)
| | (11) returning to ‘decode_options’ from
‘find_argp_option’
|13863 | if (opt && opt->arg)
| | ~ ~~~~~~~~
| | | |
| | | (13) ...to here
| | (12) following ‘true’ branch (when ‘opt’ is
non-NULL)...
|
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-07-25 16:37 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-25 16:37 [Bug analyzer/106436] New: -Wanalyzer-null-dereference false positive suggests data corruption in GCC eggert at cs dot ucla.edu
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).