aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/checker-event.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2022-12-02 16:30:51 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2022-12-02 16:30:51 -0500
commitf5758fe5b430ef3447fbab947fcea32a1d995f36 (patch)
treee09801d792bb57588af124eb1c9175b5e64d74ad /gcc/analyzer/checker-event.cc
parent1998db0fa1f78e373c88daea8bb339d32b41e6aa (diff)
downloadgcc-f5758fe5b430ef3447fbab947fcea32a1d995f36.zip
gcc-f5758fe5b430ef3447fbab947fcea32a1d995f36.tar.gz
gcc-f5758fe5b430ef3447fbab947fcea32a1d995f36.tar.bz2
analyzer: fixes to region creation messages [PR107851]
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>
Diffstat (limited to 'gcc/analyzer/checker-event.cc')
-rw-r--r--gcc/analyzer/checker-event.cc115
1 files changed, 54 insertions, 61 deletions
diff --git a/gcc/analyzer/checker-event.cc b/gcc/analyzer/checker-event.cc
index a3e0433..98f1053 100644
--- a/gcc/analyzer/checker-event.cc
+++ b/gcc/analyzer/checker-event.cc
@@ -293,84 +293,77 @@ statement_event::get_desc (bool) const
/* class region_creation_event : public checker_event. */
-region_creation_event::region_creation_event (const region *reg,
- tree capacity,
- enum rce_kind kind,
- location_t loc,
+region_creation_event::region_creation_event (location_t loc,
tree fndecl,
int depth)
-: checker_event (EK_REGION_CREATION, loc, fndecl, depth),
- m_reg (reg),
- m_capacity (capacity),
- m_rce_kind (kind)
+: checker_event (EK_REGION_CREATION, loc, fndecl, depth)
{
- if (m_rce_kind == RCE_CAPACITY)
- gcc_assert (capacity);
}
-/* Implementation of diagnostic_event::get_desc vfunc for
- region_creation_event.
- There are effectively 3 kinds of region_region_event, to
- avoid combinatorial explosion by trying to convy the
- information in a single message. */
+/* The various region_creation_event subclasses' get_desc
+ implementations. */
label_text
-region_creation_event::get_desc (bool can_colorize) const
+region_creation_event_memory_space::get_desc (bool) const
{
- if (m_pending_diagnostic)
+ switch (m_mem_space)
{
- label_text custom_desc
- = m_pending_diagnostic->describe_region_creation_event
- (evdesc::region_creation (can_colorize, m_reg));
- if (custom_desc.get ())
- return custom_desc;
+ default:
+ return label_text::borrow ("region created here");
+ case MEMSPACE_STACK:
+ return label_text::borrow ("region created on stack here");
+ case MEMSPACE_HEAP:
+ return label_text::borrow ("region created on heap here");
}
+}
- switch (m_rce_kind)
+label_text
+region_creation_event_capacity::get_desc (bool can_colorize) const
+{
+ gcc_assert (m_capacity);
+ if (TREE_CODE (m_capacity) == INTEGER_CST)
{
- default:
- gcc_unreachable ();
-
- case RCE_MEM_SPACE:
- switch (m_reg->get_memory_space ())
- {
- default:
- return label_text::borrow ("region created here");
- case MEMSPACE_STACK:
- return label_text::borrow ("region created on stack here");
- case MEMSPACE_HEAP:
- return label_text::borrow ("region created on heap here");
- }
- break;
+ unsigned HOST_WIDE_INT hwi = tree_to_uhwi (m_capacity);
+ return make_label_text_n (can_colorize,
+ hwi,
+ "capacity: %wu byte",
+ "capacity: %wu bytes",
+ hwi);
+ }
+ else
+ return make_label_text (can_colorize,
+ "capacity: %qE bytes", m_capacity);
+}
- case RCE_CAPACITY:
- gcc_assert (m_capacity);
+label_text
+region_creation_event_allocation_size::get_desc (bool can_colorize) const
+{
+ if (m_capacity)
+ {
if (TREE_CODE (m_capacity) == INTEGER_CST)
- {
- unsigned HOST_WIDE_INT hwi = tree_to_uhwi (m_capacity);
- if (hwi == 1)
- return make_label_text (can_colorize,
- "capacity: %wu byte", hwi);
- else
- return make_label_text (can_colorize,
- "capacity: %wu bytes", hwi);
- }
+ return make_label_text_n (can_colorize,
+ tree_to_uhwi (m_capacity),
+ "allocated %E byte here",
+ "allocated %E bytes here",
+ m_capacity);
else
return make_label_text (can_colorize,
- "capacity: %qE bytes", m_capacity);
-
- case RCE_DEBUG:
- {
- pretty_printer pp;
- pp_format_decoder (&pp) = default_tree_printer;
- pp_string (&pp, "region creation: ");
- m_reg->dump_to_pp (&pp, true);
- if (m_capacity)
- pp_printf (&pp, " capacity: %qE", m_capacity);
- return label_text::take (xstrdup (pp_formatted_text (&pp)));
- }
- break;
+ "allocated %qE bytes here",
+ m_capacity);
}
+ return make_label_text (can_colorize, "allocated here");
+}
+
+label_text
+region_creation_event_debug::get_desc (bool) const
+{
+ pretty_printer pp;
+ pp_format_decoder (&pp) = default_tree_printer;
+ pp_string (&pp, "region creation: ");
+ m_reg->dump_to_pp (&pp, true);
+ if (m_capacity)
+ pp_printf (&pp, " capacity: %qE", m_capacity);
+ return label_text::take (xstrdup (pp_formatted_text (&pp)));
}
/* class function_entry_event : public checker_event. */