https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104069
Bug ID: 104069
Summary: -Werror=use-after-free false positive on
elfutils-0.186
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: slyfox at gcc dot gnu.org
CC: dmalcolm at gcc dot gnu.org
Target Milestone: ---
Originally observed on elfutils-0.186 (which builds with -Werror by default).
Here is my attempt to extract simplified example:
typedef long unsigned int size_t;
extern void *realloc(void *__ptr, size_t __size)
__attribute__((__nothrow__, __leaf__))
__attribute__((__warn_unused_result__)) __attribute__((__alloc_size__(2)));
void * __libdw_unzstd(size_t todo) {
void * sb = 0;
for(;;) {
// ran ony once
if (!sb) {
char * b = realloc(sb, todo);
if (!b)
break;
sb = b;
}
todo -= 1;
if (todo == 0)
break;
}
// shrink buffer: leave only one byte for simplicity
char * b = realloc(sb, 1);
if (b) {
sb = b;
} else {
// realloc failed mysteriously, leave 'sb' untouched.
}
return sb;
}
$ gcc-12.0.0 -O2 -std=gnu99 -Wall -Werror -c zstd.c.c
zstd.c.c: In function ‘__libdw_unzstd’:
zstd.c.c:35:10: error: pointer ‘sb’ may be used after ‘realloc’
[-Werror=use-after-free]
35 | return sb;
| ^~
zstd.c.c:28:14: note: call to ‘realloc’ here
28 | char * b = realloc(sb, 1);
| ^~~~~~~~~~~~~~
cc1: all warnings being treated as errors
I think it's a proper false positive. Original code is not as contrived (but I
think it's still correct):
https://sourceware.org/git/?p=elfutils.git;a=blob;f=libdwfl/gzip.c;h=ba8ecfba6c316b261ee38bb288ab163664ade9e5;hb=983e86fd89e8bf02f2d27ba5dce5bf078af4ceda#l180
$ gcc-12.0.0 -v
Using built-in specs.
COLLECT_GCC=/<<NIX>>/gcc-12.0.0/bin/gcc
COLLECT_LTO_WRAPPER=/<<NIX>>/gcc-12.0.0/libexec/gcc/x86_64-unknown-linux-gnu/12.0.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with:
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 12.0.0 20220116 (experimental) (GCC)