aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/engine.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2023-02-15 14:52:02 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2023-02-15 14:53:14 -0500
commitb03a10b0b25cef4928ccead4c8a461d3674dbe86 (patch)
treeb4eb3fb39d6340de1de519e2837cfd1e9843444f /gcc/analyzer/engine.cc
parent0979973c8ea33dd357beb37bd124c1e81cc05970 (diff)
downloadgcc-b03a10b0b25cef4928ccead4c8a461d3674dbe86.zip
gcc-b03a10b0b25cef4928ccead4c8a461d3674dbe86.tar.gz
gcc-b03a10b0b25cef4928ccead4c8a461d3674dbe86.tar.bz2
analyzer: fix uninit false +ves [PR108664,PR108666,PR108725]
This patch updates poisoned_value_diagnostic so that, where possible, it checks to see if the value is still poisoned along the execution path seen during feasibility analysis, rather than just that seen in the exploded graph. Integration testing shows this reduction in the number of false positives: -Wanalyzer-use-of-uninitialized-value: 191 -> 153 (-38) where the changes happen in: coreutils-9.1: 34 -> 20 (-14) qemu-7.2.0: 78 -> 54 (-24) gcc/analyzer/ChangeLog: PR analyzer/108664 PR analyzer/108666 PR analyzer/108725 * diagnostic-manager.cc (epath_finder::get_best_epath): Add "target_stmt" param. (epath_finder::explore_feasible_paths): Likewise. (epath_finder::process_worklist_item): Likewise. (saved_diagnostic::calc_best_epath): Pass m_stmt to epath_finder::get_best_epath. * engine.cc (feasibility_state::maybe_update_for_edge): Move per-stmt logic to... (feasibility_state::update_for_stmt): ...this new function. * exploded-graph.h (feasibility_state::update_for_stmt): New decl. * feasible-graph.cc (feasible_node::get_state_at_stmt): New. * feasible-graph.h: Include "analyzer/exploded-graph.h". (feasible_node::get_state_at_stmt): New decl. * infinite-recursion.cc (infinite_recursion_diagnostic::check_valid_fpath_p): Update for vfunc signature change. * pending-diagnostic.h (pending_diagnostic::check_valid_fpath_p): Convert first param to a reference. Add stmt param. * region-model.cc: Include "analyzer/feasible-graph.h". (poisoned_value_diagnostic::poisoned_value_diagnostic): Add "check_expr" param. (poisoned_value_diagnostic::check_valid_fpath_p): New. (poisoned_value_diagnostic::m_check_expr): New field. (region_model::check_for_poison): Attempt to supply a check_expr to the diagnostic (region_model::deref_rvalue): Add NULL for new check_expr param of poisoned_value_diagnostic. (region_model::get_or_create_region_for_heap_alloc): Don't reuse regions that are marked as TOUCHED. gcc/testsuite/ChangeLog: PR analyzer/108664 PR analyzer/108666 PR analyzer/108725 * gcc.dg/analyzer/coreutils-cksum-pr108664.c: New test. * gcc.dg/analyzer/coreutils-sum-pr108666.c: New test. * gcc.dg/analyzer/torture/uninit-pr108725.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/analyzer/engine.cc')
-rw-r--r--gcc/analyzer/engine.cc30
1 files changed, 19 insertions, 11 deletions
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 8982d9d..24ded26 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -4823,17 +4823,7 @@ feasibility_state::maybe_update_for_edge (logger *logger,
auto_cfun sentinel (src_point.get_function ());
input_location = stmt->location;
- if (const gassign *assign = dyn_cast <const gassign *> (stmt))
- m_model.on_assignment (assign, NULL);
- else if (const gasm *asm_stmt = dyn_cast <const gasm *> (stmt))
- m_model.on_asm_stmt (asm_stmt, NULL);
- else if (const gcall *call = dyn_cast <const gcall *> (stmt))
- {
- bool unknown_side_effects = m_model.on_call_pre (call, NULL);
- m_model.on_call_post (call, unknown_side_effects, NULL);
- }
- else if (const greturn *return_ = dyn_cast <const greturn *> (stmt))
- m_model.on_return (return_, NULL);
+ update_for_stmt (stmt);
}
const superedge *sedge = eedge->m_sedge;
@@ -4910,6 +4900,24 @@ feasibility_state::maybe_update_for_edge (logger *logger,
return true;
}
+/* Update this object for the effects of STMT. */
+
+void
+feasibility_state::update_for_stmt (const gimple *stmt)
+{
+ if (const gassign *assign = dyn_cast <const gassign *> (stmt))
+ m_model.on_assignment (assign, NULL);
+ else if (const gasm *asm_stmt = dyn_cast <const gasm *> (stmt))
+ m_model.on_asm_stmt (asm_stmt, NULL);
+ else if (const gcall *call = dyn_cast <const gcall *> (stmt))
+ {
+ bool unknown_side_effects = m_model.on_call_pre (call, NULL);
+ m_model.on_call_post (call, unknown_side_effects, NULL);
+ }
+ else if (const greturn *return_ = dyn_cast <const greturn *> (stmt))
+ m_model.on_return (return_, NULL);
+}
+
/* Dump this object to PP. */
void