diff options
author | David Malcolm <dmalcolm@redhat.com> | 2021-07-16 15:47:06 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2021-07-16 15:47:06 -0400 |
commit | 9ea10c480565fa42b1804fb436f7e26ca77b71a3 (patch) | |
tree | 06cc69c3752438b1cdccfa134b6e763d9a1ad303 /gcc/analyzer/program-state.cc | |
parent | 5932dd35eaa816e8d9b6406c6c433395ff5b6162 (diff) | |
download | gcc-9ea10c480565fa42b1804fb436f7e26ca77b71a3.zip gcc-9ea10c480565fa42b1804fb436f7e26ca77b71a3.tar.gz gcc-9ea10c480565fa42b1804fb436f7e26ca77b71a3.tar.bz2 |
analyzer: add __analyzer_dump_state
gcc/analyzer/ChangeLog:
* engine.cc (exploded_node::on_stmt_pre): Handle
__analyzer_dump_state.
* program-state.cc (extrinsic_state::get_sm_idx_by_name): New.
(program_state::impl_call_analyzer_dump_state): New.
* program-state.h (extrinsic_state::get_sm_idx_by_name): New decl.
(program_state::impl_call_analyzer_dump_state): New decl.
* region-model-impl-calls.cc
(call_details::get_arg_string_literal): New.
* region-model.h (call_details::get_arg_string_literal): New decl.
gcc/ChangeLog:
* doc/analyzer.texi: Add __analyzer_dump_state.
gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/analyzer-decls.h (__analyzer_dump_state): New.
* gcc.dg/analyzer/dump-state.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/analyzer/program-state.cc')
-rw-r--r-- | gcc/analyzer/program-state.cc | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc index cc53aef..3081217 100644 --- a/gcc/analyzer/program-state.cc +++ b/gcc/analyzer/program-state.cc @@ -131,6 +131,27 @@ extrinsic_state::get_model_manager () const return NULL; /* for selftests. */ } +/* Try to find a state machine named NAME. + If found, return true and write its index to *OUT. + Otherwise return false. */ + +bool +extrinsic_state::get_sm_idx_by_name (const char *name, unsigned *out) const +{ + unsigned i; + state_machine *sm; + FOR_EACH_VEC_ELT (m_checkers, i, sm) + if (0 == strcmp (name, sm->get_name ())) + { + /* Found NAME. */ + *out = i; + return true; + } + + /* NAME not found. */ + return false; +} + /* struct sm_state_map::entry_t. */ int @@ -1290,6 +1311,34 @@ program_state::detect_leaks (const program_state &src_state, dest_state.m_region_model->unset_dynamic_extents (reg); } +/* Handle calls to "__analyzer_dump_state". */ + +void +program_state::impl_call_analyzer_dump_state (const gcall *call, + const extrinsic_state &ext_state, + region_model_context *ctxt) +{ + call_details cd (call, m_region_model, ctxt); + const char *sm_name = cd.get_arg_string_literal (0); + if (!sm_name) + { + error_at (call->location, "cannot determine state machine"); + return; + } + unsigned sm_idx; + if (!ext_state.get_sm_idx_by_name (sm_name, &sm_idx)) + { + error_at (call->location, "unrecognized state machine %qs", sm_name); + return; + } + const sm_state_map *smap = m_checker_states[sm_idx]; + + const svalue *sval = cd.get_arg_svalue (1); + + state_machine::state_t state = smap->get_state (sval, ext_state); + warning_at (call->location, 0, "state: %qs", state->get_name ()); +} + #if CHECKING_P namespace selftest { |