aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/checker-event.cc
AgeCommit message (Collapse)AuthorFilesLines
2023-01-19analyzer: use dominator info in -Wanalyzer-deref-before-check [PR108455]David Malcolm1-3/+5
My integration testing [1] of -fanalyzer in GCC 13 is showing a lot of diagnostics from the new -Wanalyzer-deref-before-check warning on real-world C projects, and most of these seem to be false positives. This patch updates the warning to make it much less likely to fire: - only intraprocedural cases are now reported - reject cases in which there are control flow paths to the check that didn't come through the dereference, by looking at BB dominator information. This fixes a false positive seen in git-2.39.0's pack-revindex.c: load_revindex_from_disk (PR analyzer/108455), in which a shared "cleanup:" section checks "data" for NULL, and depending on how much of the function is executed "data" might or might not have already been dereferenced. The counts of -Wanalyzer-deref-before-check diagnostics in [1] before/after this patch show this improvement: Known false positives: 6 -> 0 (-6) Known true positives: 1 -> 1 Unclassified positives: 123 -> 63 (-60) [1] https://github.com/davidmalcolm/gcc-analyzer-integration-tests gcc/analyzer/ChangeLog: PR analyzer/108455 * analyzer.h (class checker_event): New forward decl. (class state_change_event): Indent. (class warning_event): New forward decl. * checker-event.cc (state_change_event::state_change_event): Add "enode" param. (warning_event::get_desc): Update for new param of evdesc::final_event ctor. * checker-event.h (state_change_event::state_change_event): Add "enode" param. (state_change_event::get_exploded_node): New accessor. (state_change_event::m_enode): New field. (warning_event::warning_event): New "enode" param. (warning_event::get_exploded_node): New accessor. (warning_event::m_enode): New field. * diagnostic-manager.cc (state_change_event_creator::on_global_state_change): Pass src_node to state_change_event ctor. (state_change_event_creator::on_state_change): Likewise. (null_assignment_sm_context::set_next_state): Pass NULL for new param of state_change_event ctor. * infinite-recursion.cc (infinite_recursion_diagnostic::add_final_event): Update for new param of warning_event ctor. * pending-diagnostic.cc (pending_diagnostic::add_final_event): Pass enode to warning_event ctor. * pending-diagnostic.h (evdesc::final_event): Add reference to warning_event. * sm-malloc.cc: Include "analyzer/checker-event.h" and "analyzer/exploded-graph.h". (deref_before_check::deref_before_check): Initialize new fields. (deref_before_check::emit): Reject warnings in which we were unable to determine the enodes of the dereference and the check. Reject warnings interprocedural warnings. Reject warnings in which the dereference doesn't dominate the check. (deref_before_check::describe_state_change): Set m_deref_enode. (deref_before_check::describe_final_event): Set m_check_enode. (deref_before_check::m_deref_enode): New field. (deref_before_check::m_check_enode): New field. gcc/testsuite/ChangeLog: PR analyzer/108455 * gcc.dg/analyzer/deref-before-check-1.c: Add test coverage involving dominance. * gcc.dg/analyzer/deref-before-check-pr108455-1.c: New test. * gcc.dg/analyzer/deref-before-check-pr108455-git-pack-revindex.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-01-16Update copyright years.Jakub Jelinek1-1/+1
2022-12-02analyzer: introduce struct event_loc_infoDavid Malcolm1-26/+29
gcc/analyzer/ChangeLog: * analyzer.h (struct event_loc_info): New forward decl. * bounds-checking.cc: Use event_loc_info throughout to bundle the loc, fndecl, depth triples. * call-info.cc: Likewise. * checker-event.cc: Likewise. * checker-event.h (struct event_loc_info): New decl. Use it throughout to bundle the loc, fndecl, depth triples. * checker-path.cc: Likewise. * checker-path.h: Likewise. * diagnostic-manager.cc: Likewise. * engine.cc: Likewise. * infinite-recursion.cc: Likewise. * pending-diagnostic.cc: Likewise. * pending-diagnostic.h: Likewise. * region-model.cc: Likewise. * sm-signal.cc: Likewise. * varargs.cc: Likewise. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-12-02analyzer: fixes to region creation messages [PR107851]David Malcolm1-61/+54
In r13-2573-gc81b60b8c6ff3d I split up the analyzer's region-creation events to describe the memory space and capacity of the region as two separate events to avoid combinatorial explosion of message wordings. However I didn't take into account r13-1405-ge6c3bb379f515b which added a pending_diagnostic::describe_region_creation_event vfunc which could change the wording of region creation events. Hence for: #include <stdlib.h> #include <stdint.h> void test () { int32_t *ptr = malloc (1); free (ptr); } trunk currently emits: Compiler Explorer (x86_64 trunk): https://godbolt.org/z/e3Td7c9s5: <source>: In function 'test': <source>:6:18: warning: allocated buffer size is not a multiple of the pointee's size [CWE-131] [-Wanalyzer-allocation-size] 6 | int32_t *ptr = malloc (1); | ^~~~~~~~~~ 'test': events 1-3 | | 6 | int32_t *ptr = malloc (1); | | ^~~~~~~~~~ | | | | | (1) allocated 1 bytes here | | (2) allocated 1 bytes here | | (3) assigned to 'int32_t *' {aka 'int *'} here; 'sizeof (int32_t {aka int})' is '4' | where events (1) and (2) are different region_creation_events that have had their wording overridden (also, with a "1 bytes" issue). This patch reorganizes region creation events so that each pending_diagnostic instead creates the events that is appropriate for it, and the events have responsibility for their own wording. With this patch, the above emits: <source>: In function 'test': <source>:6:18: warning: allocated buffer size is not a multiple of the pointee's size [CWE-131] [-Wanalyzer-allocation-size] 6 | int32_t *ptr = malloc (1); | ^~~~~~~~~~ 'test': events 1-2 | | 6 | int32_t *ptr = malloc (1); | | ^~~~~~~~~~ | | | | | (1) allocated 1 byte here | | (2) assigned to 'int32_t *' {aka 'int *'} here; 'sizeof (int32_t {aka int})' is '4' | fixing the duplicate event, and fixing the singular/plural issue. gcc/analyzer/ChangeLog: PR analyzer/107851 * analyzer.cc (make_label_text_n): Convert param "n" from int to unsigned HOST_WIDE_INT. * analyzer.h (make_label_text_n): Likewise for decl. * bounds-checking.cc: Include "analyzer/checker-event.h" and "analyzer/checker-path.h". (out_of_bounds::add_region_creation_events): New. (concrete_past_the_end::describe_region_creation_event): Replace with... (concrete_past_the_end::add_region_creation_events): ...this. (symbolic_past_the_end::describe_region_creation_event): Delete. * checker-event.cc (region_creation_event::region_creation_event): Update for dropping all member data. (region_creation_event::get_desc): Delete, splitting out into region_creation_event_memory_space::get_desc, region_creation_event_capacity::get_desc, and region_creation_event_debug::get_desc. (region_creation_event_memory_space::get_desc): New. (region_creation_event_capacity::get_desc): New. (region_creation_event_allocation_size::get_desc): New. (region_creation_event_debug::get_desc): New. * checker-event.h: Include "analyzer/program-state.h". (enum rce_kind): Delete. (class region_creation_event): Drop all member data. (region_creation_event::region_creation_event): Make protected. (region_creation_event::get_desc): Delete. (class region_creation_event_memory_space): New. (class region_creation_event_capacity): New. (class region_creation_event_allocation_size): New. (class region_creation_event_debug): New. * checker-path.cc (checker_path::add_region_creation_events): Add "pd" param. Call pending_diangnostic::add_region_creation_events. Update for conversion of RCE_DEBUG to region_creation_event_debug. * checker-path.h (checker_path::add_region_creation_events): Add "pd" param. * diagnostic-manager.cc (diagnostic_manager::build_emission_path): Pass pending_diagnostic to emission_path::add_region_creation_events. (diagnostic_manager::build_emission_path): Pass path_builder to add_event_on_final_node. (diagnostic_manager::add_event_on_final_node): Add "pb" param. Pass pending_diagnostic to emission_path::add_region_creation_events. (diagnostic_manager::add_events_for_eedge): Pass pending_diagnostic to emission_path::add_region_creation_events. * diagnostic-manager.h (diagnostic_manager::add_event_on_final_node): Add "pb" param. * pending-diagnostic.cc (pending_diagnostic::add_region_creation_events): New. * pending-diagnostic.h (struct region_creation): Delete. (pending_diagnostic::describe_region_creation_event): Delete. (pending_diagnostic::add_region_creation_events): New vfunc. * region-model.cc: Include "analyzer/checker-event.h" and "analyzer/checker-path.h". (dubious_allocation_size::dubious_allocation_size): Initialize m_has_allocation_event. (dubious_allocation_size::describe_region_creation_event): Delete. (dubious_allocation_size::describe_final_event): Update for replacement of m_allocation_event with m_has_allocation_event. (dubious_allocation_size::add_region_creation_events): New. (dubious_allocation_size::m_allocation_event): Replace with... (dubious_allocation_size::m_has_allocation_event): ...this. gcc/testsuite/ChangeLog: PR analyzer/107851 * gcc.dg/analyzer/allocation-size-4.c: Update expected wording. * gcc.dg/analyzer/allocation-size-multiline-1.c: New test. * gcc.dg/analyzer/allocation-size-multiline-2.c: New test. * gcc.dg/analyzer/out-of-bounds-multiline-1.c: Update expected wording. * gcc.dg/analyzer/out-of-bounds-multiline-2.c: New test. * gcc.dg/analyzer/out-of-bounds-read-char-arr.c: Update expected wording. * gcc.dg/analyzer/out-of-bounds-read-int-arr.c: Likewise. * gcc.dg/analyzer/out-of-bounds-write-char-arr.c: Likewise. * gcc.dg/analyzer/out-of-bounds-write-int-arr.c: Likewise. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-11-16analyzer: split out checker-path.cc into a new checker-event.ccDavid Malcolm1-0/+1213
gcc/ChangeLog: * Makefile.in (ANALYZER_OBJS): Add analyzer/checker-event.o. gcc/analyzer/ChangeLog: * checker-event.cc: New file, split out from... * checker-path.cc: ...this file. Signed-off-by: David Malcolm <dmalcolm@redhat.com>