diff options
Diffstat (limited to 'gcc/analyzer/program-state.cc')
-rw-r--r-- | gcc/analyzer/program-state.cc | 121 |
1 files changed, 68 insertions, 53 deletions
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc index 21f78e5..c0befac 100644 --- a/gcc/analyzer/program-state.cc +++ b/gcc/analyzer/program-state.cc @@ -28,6 +28,8 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "digraph.h" #include "diagnostic-event-id.h" +#include "diagnostic-state.h" +#include "graphviz.h" #include "text-art/tree-widget.h" #include "text-art/dump.h" @@ -48,6 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/state-purge.h" #include "analyzer/call-summary.h" #include "analyzer/analyzer-selftests.h" +#include "analyzer/ana-state-to-diagnostic-state.h" #if ENABLE_ANALYZER @@ -112,7 +115,7 @@ extrinsic_state::get_model_manager () const if (m_engine) return m_engine->get_model_manager (); else - return NULL; /* for selftests. */ + return nullptr; /* for selftests. */ } /* Try to find a state machine named NAME. @@ -255,7 +258,7 @@ DEBUG_FUNCTION void sm_state_map::dump (bool simple) const { tree_dump_pretty_printer pp (stderr); - print (NULL, simple, true, &pp); + print (nullptr, simple, true, &pp); pp_newline (&pp); } @@ -417,7 +420,7 @@ sm_state_map::operator== (const sm_state_map &other) const const svalue *sval = (*iter).first; entry_t e = (*iter).second; entry_t *other_slot = const_cast <map_t &> (other.m_map).get (sval); - if (other_slot == NULL) + if (other_slot == nullptr) return false; if (e != *other_slot) return false; @@ -498,7 +501,7 @@ sm_state_map::get_origin (const svalue *sval, if (slot) return slot->m_origin; else - return NULL; + return nullptr; } /* Set the state of SID within MODEL to STATE, recording that @@ -511,7 +514,7 @@ sm_state_map::set_state (region_model *model, const svalue *origin, const extrinsic_state &ext_state) { - if (model == NULL) + if (model == nullptr) return; /* Reject attempts to set state on UNKNOWN/POISONED. */ @@ -768,7 +771,7 @@ sm_state_map::on_unknown_change (const svalue *sval, for (svalue_set::iterator iter = svals_to_unset.begin (); iter != svals_to_unset.end (); ++iter) - impl_set_state (*iter, (state_machine::state_t)0, NULL, ext_state); + impl_set_state (*iter, (state_machine::state_t)0, nullptr, ext_state); } /* Purge state for things involving SVAL. @@ -799,7 +802,7 @@ sm_state_map::purge_state_involving (const svalue *sval, for (svalue_set::iterator iter = svals_to_unset.begin (); iter != svals_to_unset.end (); ++iter) - impl_set_state (*iter, (state_machine::state_t)0, NULL, ext_state); + impl_set_state (*iter, (state_machine::state_t)0, nullptr, ext_state); } /* Comparator for imposing an order on sm_state_map instances. */ @@ -909,7 +912,7 @@ sm_state_map::can_merge_with_p (const sm_state_map &other, state_machine::state_t other_state = other.get_state (sval, ext_state); if (state_machine::state_t merged_state = sm.maybe_get_merged_state (this_state, other_state)) - (*out)->impl_set_state (sval, merged_state, NULL, ext_state); + (*out)->impl_set_state (sval, merged_state, nullptr, ext_state); else return false; } @@ -923,7 +926,7 @@ sm_state_map::can_merge_with_p (const sm_state_map &other, /* program_state's ctor. */ program_state::program_state (const extrinsic_state &ext_state) -: m_region_model (NULL), +: m_region_model (nullptr), m_checker_states (ext_state.get_num_checkers ()), m_valid (true) { @@ -957,8 +960,8 @@ sm_state_map::replay_call_summary (call_summary_replay &r, const svalue *caller_origin = (summary_origin ? r.convert_svalue_from_summary (summary_origin) - : NULL); - // caller_origin can be NULL. + : nullptr); + // caller_origin can be nullptr. m_map.put (caller_sval, entry_t (kv.second.m_state, caller_origin)); } m_global_state = summary.m_global_state; @@ -1006,7 +1009,7 @@ program_state::program_state (program_state &&other) : m_region_model (other.m_region_model), m_checker_states (other.m_checker_states.length ()) { - other.m_region_model = NULL; + other.m_region_model = nullptr; int i; sm_state_map *smap; @@ -1224,6 +1227,18 @@ program_state::make_dump_widget (const text_art::dump_widget_info &dwi) const return state_widget; } +void +program_state::dump_dot (const extrinsic_state &ext_state) const +{ + auto doc = make_xml (ext_state); + auto graph = make_dot_graph_from_xml_state (*doc); + + pretty_printer pp; + dot::writer w (pp); + graph->print (w); + pp_flush (&pp); +} + /* Update this program_state to reflect a top-level call to FUN. The params will have initial_svalues. */ @@ -1322,7 +1337,7 @@ program_state::on_edge (exploded_graph &eg, return false; program_state::detect_leaks (enode->get_state (), *this, - NULL, eg.get_ext_state (), + nullptr, eg.get_ext_state (), &ctxt); return true; @@ -1346,7 +1361,7 @@ program_state::push_call (exploded_graph &eg, &enode->get_state (), this, uncertainty, - NULL, + nullptr, last_stmt); m_region_model->update_for_gcall (call_stmt, &ctxt); } @@ -1369,7 +1384,7 @@ program_state::returning_call (exploded_graph &eg, &enode->get_state (), this, uncertainty, - NULL, + nullptr, last_stmt); m_region_model->update_for_return_gcall (call_stmt, &ctxt); } @@ -1427,7 +1442,7 @@ program_state::prune_for_point (exploded_graph &eg, temporaries keep the value reachable until the frame is popped. */ const svalue *sval - = new_state.m_region_model->get_store_value (reg, NULL); + = new_state.m_region_model->get_store_value (reg, nullptr); if (!new_state.can_purge_p (eg.get_ext_state (), sval) && SSA_NAME_VAR (ssa_name)) { @@ -1486,9 +1501,9 @@ program_state::prune_for_point (exploded_graph &eg, impl_region_model_context ctxt (eg, enode_for_diag, this, &new_state, - uncertainty, NULL, + uncertainty, nullptr, point.get_stmt ()); - detect_leaks (*this, new_state, NULL, eg.get_ext_state (), &ctxt); + detect_leaks (*this, new_state, nullptr, eg.get_ext_state (), &ctxt); } } @@ -1660,7 +1675,7 @@ program_state::detect_leaks (const program_state &src_state, *might* still be reachable in dst_state. */ svalue_set known_src_svalues; src_state.m_region_model->get_reachable_svalues (&known_src_svalues, - NULL, NULL); + nullptr, nullptr); svalue_set maybe_dest_svalues; dest_state.m_region_model->get_reachable_svalues (&maybe_dest_svalues, extra_sval, uncertainty); @@ -1778,7 +1793,7 @@ test_sm_state_map () tree y = build_global_decl ("y", integer_type_node); tree z = build_global_decl ("z", integer_type_node); - std::unique_ptr<state_machine> sm = make_malloc_state_machine (NULL); + std::unique_ptr<state_machine> sm = make_malloc_state_machine (nullptr); state_machine::state_t start = sm->get_start_state (); std::vector<std::unique_ptr<state_machine>> checkers; const state_machine &borrowed_sm = *sm.get (); @@ -1792,9 +1807,9 @@ test_sm_state_map () const state_machine::state_t TEST_STATE_42 = &test_state_42; region_model_manager mgr; region_model model (&mgr); - const svalue *x_sval = model.get_rvalue (x, NULL); - const svalue *y_sval = model.get_rvalue (y, NULL); - const svalue *z_sval = model.get_rvalue (z, NULL); + const svalue *x_sval = model.get_rvalue (x, nullptr); + const svalue *y_sval = model.get_rvalue (y, nullptr); + const svalue *z_sval = model.get_rvalue (z, nullptr); sm_state_map map (borrowed_sm); ASSERT_TRUE (map.is_empty_p ()); @@ -1821,16 +1836,16 @@ test_sm_state_map () { region_model_manager mgr; region_model model (&mgr); - const svalue *x_sval = model.get_rvalue (x, NULL); - const svalue *y_sval = model.get_rvalue (y, NULL); - const svalue *z_sval = model.get_rvalue (z, NULL); + const svalue *x_sval = model.get_rvalue (x, nullptr); + const svalue *y_sval = model.get_rvalue (y, nullptr); + const svalue *z_sval = model.get_rvalue (z, nullptr); sm_state_map map (borrowed_sm); ASSERT_TRUE (map.is_empty_p ()); ASSERT_EQ (map.get_state (x_sval, ext_state), start); ASSERT_EQ (map.get_state (y_sval, ext_state), start); - model.add_constraint (x, EQ_EXPR, y, NULL); + model.add_constraint (x, EQ_EXPR, y, nullptr); /* Setting x to a state should also update y, as they are in the same equivalence class. */ @@ -1845,8 +1860,8 @@ test_sm_state_map () { region_model_manager mgr; region_model model (&mgr); - const svalue *y_sval = model.get_rvalue (y, NULL); - const svalue *z_sval = model.get_rvalue (z, NULL); + const svalue *y_sval = model.get_rvalue (y, nullptr); + const svalue *z_sval = model.get_rvalue (z, nullptr); sm_state_map map0 (borrowed_sm); sm_state_map map1 (borrowed_sm); @@ -1880,17 +1895,17 @@ test_sm_state_map () region_model_manager mgr; region_model model (&mgr); - const svalue *x_sval = model.get_rvalue (x, NULL); - const svalue *y_sval = model.get_rvalue (y, NULL); - const svalue *z_sval = model.get_rvalue (z, NULL); + const svalue *x_sval = model.get_rvalue (x, nullptr); + const svalue *y_sval = model.get_rvalue (y, nullptr); + const svalue *z_sval = model.get_rvalue (z, nullptr); - map1.impl_set_state (x_sval, TEST_STATE_2, NULL, ext_state); - map1.impl_set_state (y_sval, TEST_STATE_3, NULL, ext_state); - map1.impl_set_state (z_sval, TEST_STATE_2, NULL, ext_state); + map1.impl_set_state (x_sval, TEST_STATE_2, nullptr, ext_state); + map1.impl_set_state (y_sval, TEST_STATE_3, nullptr, ext_state); + map1.impl_set_state (z_sval, TEST_STATE_2, nullptr, ext_state); - map2.impl_set_state (z_sval, TEST_STATE_2, NULL, ext_state); - map2.impl_set_state (y_sval, TEST_STATE_3, NULL, ext_state); - map2.impl_set_state (x_sval, TEST_STATE_2, NULL, ext_state); + map2.impl_set_state (z_sval, TEST_STATE_2, nullptr, ext_state); + map2.impl_set_state (y_sval, TEST_STATE_3, nullptr, ext_state); + map2.impl_set_state (x_sval, TEST_STATE_2, nullptr, ext_state); ASSERT_EQ (map1.hash (), map2.hash ()); ASSERT_EQ (map1, map2); @@ -1908,7 +1923,7 @@ test_program_state_1 () malloc sm-state, pointing to a region on the heap. */ tree p = build_global_decl ("p", ptr_type_node); - std::unique_ptr<state_machine> sm = make_malloc_state_machine (NULL); + std::unique_ptr<state_machine> sm = make_malloc_state_machine (nullptr); const state_machine::state_t UNCHECKED_STATE = sm->get_state_by_name ("unchecked"); @@ -1920,13 +1935,13 @@ test_program_state_1 () const svalue *size_in_bytes = mgr->get_or_create_unknown_svalue (size_type_node); const region *new_reg - = model->get_or_create_region_for_heap_alloc (size_in_bytes, NULL); + = model->get_or_create_region_for_heap_alloc (size_in_bytes, nullptr); const svalue *ptr_sval = mgr->get_ptr_svalue (ptr_type_node, new_reg); - model->set_value (model->get_lvalue (p, NULL), - ptr_sval, NULL); + model->set_value (model->get_lvalue (p, nullptr), + ptr_sval, nullptr); sm_state_map *smap = s.m_checker_states[0]; - smap->impl_set_state (ptr_sval, UNCHECKED_STATE, NULL, ext_state); + smap->impl_set_state (ptr_sval, UNCHECKED_STATE, nullptr, ext_state); ASSERT_EQ (smap->get_state (ptr_sval, ext_state), UNCHECKED_STATE); } @@ -1947,9 +1962,9 @@ test_program_state_2 () program_state s (ext_state); region_model *model = s.m_region_model; - const region *p_reg = model->get_lvalue (p, NULL); - const svalue *str_sval = model->get_rvalue (string_cst_ptr, NULL); - model->set_value (p_reg, str_sval, NULL); + const region *p_reg = model->get_lvalue (p, nullptr); + const svalue *str_sval = model->get_rvalue (string_cst_ptr, nullptr); + model->set_value (p_reg, str_sval, nullptr); } /* Verify that program_states with identical sm-state can be merged, @@ -1965,7 +1980,7 @@ test_program_state_merging () engine eng; region_model_manager *mgr = eng.get_model_manager (); program_point point (program_point::origin (*mgr)); - extrinsic_state ext_state (make_malloc_state_machine (NULL), + extrinsic_state ext_state (make_malloc_state_machine (nullptr), &eng); program_state s0 (ext_state); @@ -1976,20 +1991,20 @@ test_program_state_merging () const svalue *size_in_bytes = mgr->get_or_create_unknown_svalue (size_type_node); const region *new_reg - = model0->get_or_create_region_for_heap_alloc (size_in_bytes, NULL); + = model0->get_or_create_region_for_heap_alloc (size_in_bytes, nullptr); const svalue *ptr_sval = mgr->get_ptr_svalue (ptr_type_node, new_reg); model0->set_value (model0->get_lvalue (p, &ctxt), ptr_sval, &ctxt); sm_state_map *smap = s0.m_checker_states[0]; const state_machine::state test_state ("test state", 0); const state_machine::state_t TEST_STATE = &test_state; - smap->impl_set_state (ptr_sval, TEST_STATE, NULL, ext_state); + smap->impl_set_state (ptr_sval, TEST_STATE, nullptr, ext_state); ASSERT_EQ (smap->get_state (ptr_sval, ext_state), TEST_STATE); model0->canonicalize (); /* Verify that canonicalization preserves sm-state. */ - ASSERT_EQ (smap->get_state (model0->get_rvalue (p, NULL), ext_state), + ASSERT_EQ (smap->get_state (model0->get_rvalue (p, nullptr), ext_state), TEST_STATE); /* Make a copy of the program_state. */ @@ -2006,7 +2021,7 @@ test_program_state_merging () /* Verify that the merged state has the sm-state for "p". */ region_model *merged_model = merged.m_region_model; sm_state_map *merged_smap = merged.m_checker_states[0]; - ASSERT_EQ (merged_smap->get_state (merged_model->get_rvalue (p, NULL), + ASSERT_EQ (merged_smap->get_state (merged_model->get_rvalue (p, nullptr), ext_state), TEST_STATE); @@ -2015,7 +2030,7 @@ test_program_state_merging () merged.validate (ext_state); /* Verify that the merged state still has the sm-state for "p". */ - ASSERT_EQ (merged_smap->get_state (merged_model->get_rvalue (p, NULL), + ASSERT_EQ (merged_smap->get_state (merged_model->get_rvalue (p, nullptr), ext_state), TEST_STATE); @@ -2032,7 +2047,7 @@ test_program_state_merging_2 () engine eng; region_model_manager *mgr = eng.get_model_manager (); program_point point (program_point::origin (*mgr)); - extrinsic_state ext_state (make_signal_state_machine (NULL), &eng); + extrinsic_state ext_state (make_signal_state_machine (nullptr), &eng); const state_machine::state test_state_0 ("test state 0", 0); const state_machine::state test_state_1 ("test state 1", 1); |