]> git.ipfire.org Git - thirdparty/gcc.git/commit
analyzer: show region creation events for uninit warnings
authorDavid Malcolm <dmalcolm@redhat.com>
Wed, 26 Jan 2022 21:24:08 +0000 (16:24 -0500)
committerDavid Malcolm <dmalcolm@redhat.com>
Thu, 27 Jan 2022 23:02:56 +0000 (18:02 -0500)
commit00e7d024afb80e95fb36d74b1c059468d883a850
tree86eb3697b046aaa6b4e3c7411cf8372087f9537b
parentf21f22d1baf7e90f3edbfc48040c76fb14103803
analyzer: show region creation events for uninit warnings

When reviewing the output of -fanalyzer on PR analyzer/104224 I noticed
that despite very verbose paths, the diagnostic paths for
  -Wanalyzer-use-of-uninitialized-value
don't show where the uninitialized memory is allocated.

This patch adapts and simplifies material from
  "[PATCH 3/6] analyzer: implement infoleak detection"
    https://gcc.gnu.org/pipermail/gcc-patches/2021-November/584377.html
in order to add region creation events for the pertinent region (whether
on the stack or heap).

For example, this patch extends:

malloc-1.c: In function 'test_40':
malloc-1.c:461:5: warning: use of uninitialized value '*p' [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
  461 |   i = *p;
      |   ~~^~~~
  'test_40': event 1
    |
    |  461 |   i = *p;
    |      |   ~~^~~~
    |      |     |
    |      |     (1) use of uninitialized value '*p' here
    |

to:

malloc-1.c: In function 'test_40':
malloc-1.c:461:5: warning: use of uninitialized value '*p' [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
  461 |   i = *p;
      |   ~~^~~~
  'test_40': events 1-2
    |
    |  460 |   int *p = (int*)malloc(sizeof(int*));
    |      |                  ^~~~~~~~~~~~~~~~~~~~
    |      |                  |
    |      |                  (1) region created on heap here
    |  461 |   i = *p;
    |      |   ~~~~~~
    |      |     |
    |      |     (2) use of uninitialized value '*p' here
    |

and this helps readability of the resulting warnings, especially in
more complicated cases.

gcc/analyzer/ChangeLog:
* checker-path.cc (event_kind_to_string): Handle
EK_REGION_CREATION.
(region_creation_event::region_creation_event): New.
(region_creation_event::get_desc): New.
(checker_path::add_region_creation_event): New.
* checker-path.h (enum event_kind): Add EK_REGION_CREATION.
(class region_creation_event): New subclass.
(checker_path::add_region_creation_event): New decl.
* diagnostic-manager.cc
(diagnostic_manager::emit_saved_diagnostic): Pass NULL for new
param to add_events_for_eedge when handling trailing eedge.
(diagnostic_manager::build_emission_path): Create an interesting_t
instance, allow the pending diagnostic to populate it, and pass it
to the calls to add_events_for_eedge.
(diagnostic_manager::add_events_for_eedge): Add "interest" param.
Use it to add region_creation_events for on-stack regions created
within at function entry, and when pertinent dynamically-sized
regions are created.
(diagnostic_manager::prune_for_sm_diagnostic): Add case for
EK_REGION_CREATION.
* diagnostic-manager.h (diagnostic_manager::add_events_for_eedge):
Add "interest" param.
* pending-diagnostic.cc: Include "selftest.h", "tristate.h",
"analyzer/call-string.h", "analyzer/program-point.h",
"analyzer/store.h", and "analyzer/region-model.h".
(interesting_t::add_region_creation): New.
(interesting_t::dump_to_pp): New.
* pending-diagnostic.h (struct interesting_t): New.
(pending_diagnostic::mark_interesting_stuff): New vfunc.
* region-model.cc
(poisoned_value_diagnostic::poisoned_value_diagnostic): Add
(poisoned_value_diagnostic::operator==): Compare m_pkind and
m_src_region fields.
(poisoned_value_diagnostic::mark_interesting_stuff): New.
(poisoned_value_diagnostic::m_src_region): New.
(region_model::check_for_poison): Call
get_region_for_poisoned_expr for uninit values and pass the resul
to the diagnostic.
(region_model::get_region_for_poisoned_expr): New.
(region_model::deref_rvalue): Pass NULL for
poisoned_value_diagnostic's src_region.
* region-model.h (region_model::get_region_for_poisoned_expr): New
decl.
* region.h (frame_region::get_fndecl): New.

gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/data-model-1.c: Add dg-message directives for
expected region creation events.
* gcc.dg/analyzer/malloc-1.c: Likewise.
* gcc.dg/analyzer/memset-CVE-2017-18549-1.c: Likewise.
* gcc.dg/analyzer/pr101547.c: Likewise.
* gcc.dg/analyzer/pr101875.c: Likewise.
* gcc.dg/analyzer/pr101962.c: Likewise.
* gcc.dg/analyzer/pr104224.c: Likewise.
* gcc.dg/analyzer/pr94047.c: Likewise.
* gcc.dg/analyzer/symbolic-1.c: Likewise.
* gcc.dg/analyzer/uninit-1.c: Likewise.
* gcc.dg/analyzer/uninit-4.c: Likewise.
* gcc.dg/analyzer/uninit-alloca.c: New test.
* gcc.dg/analyzer/uninit-pr94713.c: Add dg-message directive for
expected region creation event.
* gcc.dg/analyzer/uninit-pr94714.c: Likewise.
* gcc.dg/analyzer/zlib-3.c: Likewise.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
24 files changed:
gcc/analyzer/checker-path.cc
gcc/analyzer/checker-path.h
gcc/analyzer/diagnostic-manager.cc
gcc/analyzer/diagnostic-manager.h
gcc/analyzer/pending-diagnostic.cc
gcc/analyzer/pending-diagnostic.h
gcc/analyzer/region-model.cc
gcc/analyzer/region-model.h
gcc/analyzer/region.h
gcc/testsuite/gcc.dg/analyzer/data-model-1.c
gcc/testsuite/gcc.dg/analyzer/malloc-1.c
gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c
gcc/testsuite/gcc.dg/analyzer/pr101547.c
gcc/testsuite/gcc.dg/analyzer/pr101875.c
gcc/testsuite/gcc.dg/analyzer/pr101962.c
gcc/testsuite/gcc.dg/analyzer/pr104224.c
gcc/testsuite/gcc.dg/analyzer/pr94047.c
gcc/testsuite/gcc.dg/analyzer/symbolic-1.c
gcc/testsuite/gcc.dg/analyzer/uninit-1.c
gcc/testsuite/gcc.dg/analyzer/uninit-4.c
gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/analyzer/uninit-pr94713.c
gcc/testsuite/gcc.dg/analyzer/uninit-pr94714.c
gcc/testsuite/gcc.dg/analyzer/zlib-3.c