[Bug analyzer/105962] New: Unhelpful diagnostics paths from analyzer in the face of inlining
dmalcolm at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Jun 13 22:11:14 GMT 2022
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105962
Bug ID: 105962
Summary: Unhelpful diagnostics paths from analyzer in the face
of inlining
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: analyzer
Assignee: dmalcolm at gcc dot gnu.org
Reporter: dmalcolm at gcc dot gnu.org
Target Milestone: ---
Consider this double-free:
void foo (void *p)
{
__builtin_free (p);
}
void bar (void *q)
{
foo (q);
foo (q);
}
Below -O2, -fanalyzer shows the calls and returns:
../../src/gcc/testsuite/gcc.dg/analyzer/inline-1.c: In function ‘foo’:
../../src/gcc/testsuite/gcc.dg/analyzer/inline-1.c:3:3: warning: double-‘free’
of ‘p’ [CWE-415] [-Wanalyzer-double-free]
3 | __builtin_free (p);
| ^~~~~~~~~~~~~~~~~~
‘bar’: events 1-2
|
| 6 | void bar (void *q)
| | ^~~
| | |
| | (1) entry to ‘bar’
| 7 | {
| 8 | foo (q);
| | ~~~~~~~
| | |
| | (2) calling ‘foo’ from ‘bar’
|
+--> ‘foo’: events 3-4
|
| 1 | void foo (void *p)
| | ^~~
| | |
| | (3) entry to ‘foo’
| 2 | {
| 3 | __builtin_free (p);
| | ~~~~~~~~~~~~~~~~~~
| | |
| | (4) first ‘free’ here
|
<------+
|
‘bar’: events 5-6
|
| 8 | foo (q);
| | ^~~~~~~
| | |
| | (5) returning to ‘bar’ from ‘foo’
| 9 | foo (q);
| | ~~~~~~~
| | |
| | (6) passing freed pointer ‘q’ in call to ‘foo’ from ‘bar’
|
+--> ‘foo’: events 7-8
|
| 1 | void foo (void *p)
| | ^~~
| | |
| | (7) entry to ‘foo’
| 2 | {
| 3 | __builtin_free (p);
| | ~~~~~~~~~~~~~~~~~~
| | |
| | (8) second ‘free’ here; first ‘free’ was at (4)
|
but at -O2 and above, we show the unhelpful:
In function ‘foo’,
inlined from ‘bar’ at
../../src/gcc/testsuite/gcc.dg/analyzer/inline-1.c:9:3:
../../src/gcc/testsuite/gcc.dg/analyzer/inline-1.c:3:3: warning: double-‘free’
of ‘q’ [CWE-415] [-Wanalyzer-double-free]
3 | __builtin_free (p);
| ^~~~~~~~~~~~~~~~~~
‘bar’: events 1-2
|
| 3 | __builtin_free (p);
| | ^~~~~~~~~~~~~~~~~~
| | |
| | (1) first ‘free’ here
| | (2) second ‘free’ here; first ‘free’ was at (1)
which is somewhat mystifying.
This is happening because -fanalyzer is running after inlining and sees this at
the gimple level:
void bar (void * q)
{
<bb 2> [local count: 1073741824]:
__builtin_free (q_2(D));
__builtin_free (q_2(D));
return;
}
We can probably improve the readability by fixing up the events in the
diagnostic path based on the LOCATION_BLOCK inlining information captured in
the stmt location values.
I tried a version of this years ago in:
https://dmalcolm.fedorapeople.org/gcc/2020-02-20/gcc-newgit-analyzer-gcc10-analysis-gcc10-v52-relative-to-bc0f8df124f6ee12c82c5a6c1335868a15bcaecb/0012-FIXME-WIP-on-inlining-and-paths.patch
More information about the Gcc-bugs
mailing list