class plugin_analyzer_init_impl : public plugin_analyzer_init_iface
{
public:
- plugin_analyzer_init_impl (auto_delete_vec <state_machine> *checkers,
- known_function_manager *known_fn_mgr,
+ plugin_analyzer_init_impl (std::vector<std::unique_ptr<state_machine>> &checkers,
+ known_function_manager &known_fn_mgr,
logger *logger)
: m_checkers (checkers),
m_known_fn_mgr (known_fn_mgr),
void register_state_machine (std::unique_ptr<state_machine> sm) final override
{
LOG_SCOPE (m_logger);
- m_checkers->safe_push (sm.release ());
+ m_checkers.push_back (std::move (sm));
}
void register_known_function (const char *name,
std::unique_ptr<known_function> kf) final override
{
LOG_SCOPE (m_logger);
- m_known_fn_mgr->add (name, std::move (kf));
+ m_known_fn_mgr.add (name, std::move (kf));
}
logger *get_logger () const final override
}
private:
- auto_delete_vec <state_machine> *m_checkers;
- known_function_manager *m_known_fn_mgr;
+ std::vector<std::unique_ptr<state_machine>> &m_checkers;
+ known_function_manager &m_known_fn_mgr;
logger *m_logger;
};
free (filename);
}
- auto_delete_vec <state_machine> checkers;
- make_checkers (checkers, logger);
+ auto checkers = make_checkers (logger);
register_known_functions (*eng.get_known_function_manager (),
*eng.get_model_manager ());
- plugin_analyzer_init_impl data (&checkers,
- eng.get_known_function_manager (),
+ plugin_analyzer_init_impl data (checkers,
+ *eng.get_known_function_manager (),
logger);
invoke_plugin_callbacks (PLUGIN_ANALYZER_INIT, &data);
if (logger)
{
- int i;
- state_machine *sm;
- FOR_EACH_VEC_ELT (checkers, i, sm)
- logger->log ("checkers[%i]: %s", i, sm->get_name ());
+ int i = 0;
+ for (auto &sm : checkers)
+ logger->log ("checkers[%i]: %s", ++i, sm->get_name ());
}
/* Extrinsic state shared by nodes in the graph. */
- const extrinsic_state ext_state (checkers, &eng, logger);
+ const extrinsic_state ext_state (std::move (checkers), &eng, logger);
const analysis_plan plan (sg, logger);
extrinsic_state::dump_to_pp (pretty_printer *pp) const
{
pp_printf (pp, "extrinsic_state: %i checker(s)\n", get_num_checkers ());
- unsigned i;
- state_machine *checker;
- FOR_EACH_VEC_ELT (m_checkers, i, checker)
+ unsigned i = 0;
+ for (auto &checker : m_checkers)
{
- pp_printf (pp, "m_checkers[%i]: %qs\n", i, checker->get_name ());
+ pp_printf (pp, "m_checkers[%i]: %qs\n", ++i, checker->get_name ());
checker->dump_to_pp (pp);
}
}
{
auto checkers_arr = ::make_unique<json::array> ();
- unsigned i;
- state_machine *sm;
- FOR_EACH_VEC_ELT (m_checkers, i, sm)
+ for (auto &sm : m_checkers)
checkers_arr->append (sm->to_json ());
ext_state_obj->set ("checkers", std::move (checkers_arr));
}
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 ()))
+ for (size_t i = 0; i < m_checkers.size (); ++i)
+ if (0 == strcmp (name, m_checkers[i]->get_name ()))
{
/* Found NAME. */
*out = i;
tree y = build_global_decl ("y", integer_type_node);
tree z = build_global_decl ("z", integer_type_node);
- state_machine *sm = make_malloc_state_machine (NULL);
- auto_delete_vec <state_machine> checkers;
- checkers.safe_push (sm);
- engine eng;
- extrinsic_state ext_state (checkers, &eng);
+ std::unique_ptr<state_machine> sm = make_malloc_state_machine (NULL);
state_machine::state_t start = sm->get_start_state ();
+ std::vector<std::unique_ptr<state_machine>> checkers;
+ const state_machine &borrowed_sm = *sm.get ();
+ checkers.push_back (std::move (sm));
+ engine eng;
+ extrinsic_state ext_state (std::move (checkers), &eng);
/* Test setting states on svalue_id instances directly. */
{
const svalue *y_sval = model.get_rvalue (y, NULL);
const svalue *z_sval = model.get_rvalue (z, NULL);
- sm_state_map map (*sm);
+ sm_state_map map (borrowed_sm);
ASSERT_TRUE (map.is_empty_p ());
ASSERT_EQ (map.get_state (x_sval, ext_state), start);
const svalue *y_sval = model.get_rvalue (y, NULL);
const svalue *z_sval = model.get_rvalue (z, NULL);
- sm_state_map map (*sm);
+ 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);
const svalue *y_sval = model.get_rvalue (y, NULL);
const svalue *z_sval = model.get_rvalue (z, NULL);
- sm_state_map map0 (*sm);
- sm_state_map map1 (*sm);
- sm_state_map map2 (*sm);
+ sm_state_map map0 (borrowed_sm);
+ sm_state_map map1 (borrowed_sm);
+ sm_state_map map2 (borrowed_sm);
ASSERT_EQ (map0.hash (), map1.hash ());
ASSERT_EQ (map0, map1);
const state_machine::state_t TEST_STATE_2 = &test_state_2;
const state_machine::state test_state_3 ("test state 3", 3);
const state_machine::state_t TEST_STATE_3 = &test_state_3;
- sm_state_map map0 (*sm);
- sm_state_map map1 (*sm);
- sm_state_map map2 (*sm);
+ sm_state_map map0 (borrowed_sm);
+ sm_state_map map1 (borrowed_sm);
+ sm_state_map map2 (borrowed_sm);
ASSERT_EQ (map0.hash (), map1.hash ());
ASSERT_EQ (map0, map1);
malloc sm-state, pointing to a region on the heap. */
tree p = build_global_decl ("p", ptr_type_node);
- state_machine *sm = make_malloc_state_machine (NULL);
+ std::unique_ptr<state_machine> sm = make_malloc_state_machine (NULL);
const state_machine::state_t UNCHECKED_STATE
= sm->get_state_by_name ("unchecked");
- auto_delete_vec <state_machine> checkers;
- checkers.safe_push (sm);
engine eng;
- extrinsic_state ext_state (checkers, &eng);
+ extrinsic_state ext_state (std::move (sm), &eng);
region_model_manager *mgr = eng.get_model_manager ();
program_state s (ext_state);
region_model *model = s.m_region_model;
tree string_cst_ptr = build_string_literal (4, "foo");
- auto_delete_vec <state_machine> checkers;
+ std::vector<std::unique_ptr<state_machine>> checkers;
engine eng;
- extrinsic_state ext_state (checkers, &eng);
+ extrinsic_state ext_state (std::move (checkers), &eng);
program_state s (ext_state);
region_model *model = s.m_region_model;
engine eng;
region_model_manager *mgr = eng.get_model_manager ();
program_point point (program_point::origin (*mgr));
- auto_delete_vec <state_machine> checkers;
- checkers.safe_push (make_malloc_state_machine (NULL));
- extrinsic_state ext_state (checkers, &eng);
+ extrinsic_state ext_state (make_malloc_state_machine (NULL),
+ &eng);
program_state s0 (ext_state);
uncertainty_t uncertainty;
engine eng;
region_model_manager *mgr = eng.get_model_manager ();
program_point point (program_point::origin (*mgr));
- auto_delete_vec <state_machine> checkers;
- checkers.safe_push (make_signal_state_machine (NULL));
- extrinsic_state ext_state (checkers, &eng);
+ extrinsic_state ext_state (make_signal_state_machine (NULL), &eng);
const state_machine::state test_state_0 ("test state 0", 0);
const state_machine::state test_state_1 ("test state 1", 1);
class extrinsic_state
{
public:
- extrinsic_state (auto_delete_vec <state_machine> &checkers,
+ extrinsic_state (std::vector<std::unique_ptr<state_machine>> &&checkers,
engine *eng,
logger *logger = NULL)
- : m_checkers (checkers), m_logger (logger), m_engine (eng)
+ : m_checkers (std::move (checkers)),
+ m_logger (logger),
+ m_engine (eng)
{
}
+ // For use in selftests that use just one state machine
+ extrinsic_state (std::unique_ptr<state_machine> sm,
+ engine *eng,
+ logger *logger = NULL)
+ : m_logger (logger),
+ m_engine (eng)
+ {
+ m_checkers.push_back (std::move (sm));
+ }
+
const state_machine &get_sm (int idx) const
{
return *m_checkers[idx];
return m_checkers[idx]->get_name ();
}
- unsigned get_num_checkers () const { return m_checkers.length (); }
+ unsigned get_num_checkers () const { return m_checkers.size (); }
logger *get_logger () const { return m_logger; }
private:
/* The state machines. */
- auto_delete_vec <state_machine> &m_checkers;
+ std::vector<std::unique_ptr<state_machine>> m_checkers;
logger *m_logger;
engine *m_engine;
}
} // namespace
-state_machine *
+std::unique_ptr<state_machine>
make_fd_state_machine (logger *logger)
{
- return new fd_state_machine (logger);
+ return std::make_unique<fd_state_machine> (logger);
}
static bool
/* Internal interface to this file. */
-state_machine *
+std::unique_ptr<state_machine>
make_fileptr_state_machine (logger *logger)
{
- return new fileptr_state_machine (logger);
+ return std::make_unique<fileptr_state_machine> (logger);
}
/* Handler for various stdio-related builtins that merely have external
/* Internal interface to this file. */
-state_machine *
+std::unique_ptr<state_machine>
make_malloc_state_machine (logger *logger)
{
- return new malloc_state_machine (logger);
+ return std::make_unique<malloc_state_machine> (logger);
}
/* Specialcase hook for handling realloc, for use by
/* Internal interface to this file. */
-state_machine *
+std::unique_ptr<state_machine>
make_pattern_test_state_machine (logger *logger)
{
- return new pattern_test_state_machine (logger);
+ return std::make_unique<pattern_test_state_machine> (logger);
}
} // namespace ana
/* Internal interface to this file. */
-state_machine *
+std::unique_ptr<state_machine>
make_sensitive_state_machine (logger *logger)
{
- return new sensitive_state_machine (logger);
+ return std::make_unique<sensitive_state_machine> (logger);
}
} // namespace ana
/* Internal interface to this file. */
-state_machine *
+std::unique_ptr<state_machine>
make_signal_state_machine (logger *logger)
{
- return new signal_state_machine (logger);
+ return std::make_unique<signal_state_machine> (logger);
}
#if CHECKING_P
/* Internal interface to this file. */
-state_machine *
+std::unique_ptr<state_machine>
make_taint_state_machine (logger *logger)
{
- return new taint_state_machine (logger);
+ return std::make_unique<taint_state_machine> (logger);
}
/* A closed concrete range. */
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define INCLUDE_LIST
#include "analyzer/common.h"
#include "tree-diagnostic.h"
}
/* Create instances of the various state machines, each using LOGGER,
- and populate OUT with them. */
+ returning a vector of them. */
-void
-make_checkers (auto_delete_vec <state_machine> &out, logger *logger)
+std::vector<std::unique_ptr<state_machine>>
+make_checkers (logger *logger)
{
- out.safe_push (make_malloc_state_machine (logger));
- out.safe_push (make_fileptr_state_machine (logger));
- out.safe_push (make_fd_state_machine (logger));
- out.safe_push (make_taint_state_machine (logger));
- out.safe_push (make_sensitive_state_machine (logger));
- out.safe_push (make_signal_state_machine (logger));
- out.safe_push (make_va_list_state_machine (logger));
+ /* Start with a list so that we can filter it. */
+ std::list<std::unique_ptr<state_machine>> out;
+ out.push_back (make_malloc_state_machine (logger));
+ out.push_back (make_fileptr_state_machine (logger));
+ out.push_back (make_fd_state_machine (logger));
+ out.push_back (make_taint_state_machine (logger));
+ out.push_back (make_sensitive_state_machine (logger));
+ out.push_back (make_signal_state_machine (logger));
+ out.push_back (make_va_list_state_machine (logger));
/* We only attempt to run the pattern tests if it might have been manually
enabled (for DejaGnu purposes). */
if (flag_analyzer_checker)
- out.safe_push (make_pattern_test_state_machine (logger));
+ out.push_back (make_pattern_test_state_machine (logger));
if (flag_analyzer_checker)
{
- unsigned read_index, write_index;
- state_machine **sm;
-
- /* TODO: this leaks the machines
- Would be nice to log the things that were removed. */
- VEC_ORDERED_REMOVE_IF (out, read_index, write_index, sm,
- 0 != strcmp (flag_analyzer_checker,
- (*sm)->get_name ()));
+ out.remove_if ([] (auto &sm)
+ {
+ return 0 != strcmp (flag_analyzer_checker,
+ sm->get_name ());
+ });
}
+
+ std::vector<std::unique_ptr<state_machine>> out_vec;
+ for (auto &iter: out)
+ out_vec.push_back (std::move (iter));
+
+ return out_vec;
}
} // namespace ana
/* The various state_machine subclasses are hidden in their respective
implementation files. */
-extern void make_checkers (auto_delete_vec <state_machine> &out,
- logger *logger);
-
-extern state_machine *make_malloc_state_machine (logger *logger);
-extern state_machine *make_fileptr_state_machine (logger *logger);
-extern state_machine *make_taint_state_machine (logger *logger);
-extern state_machine *make_sensitive_state_machine (logger *logger);
-extern state_machine *make_signal_state_machine (logger *logger);
-extern state_machine *make_pattern_test_state_machine (logger *logger);
-extern state_machine *make_va_list_state_machine (logger *logger);
-extern state_machine *make_fd_state_machine (logger *logger);
+extern std::vector<std::unique_ptr<state_machine>>
+make_checkers (logger *logger);
+
+extern std::unique_ptr<state_machine> make_malloc_state_machine (logger *);
+extern std::unique_ptr<state_machine> make_fileptr_state_machine (logger *);
+extern std::unique_ptr<state_machine> make_taint_state_machine (logger *);
+extern std::unique_ptr<state_machine> make_sensitive_state_machine (logger *);
+extern std::unique_ptr<state_machine> make_signal_state_machine (logger *);
+extern std::unique_ptr<state_machine> make_pattern_test_state_machine (logger *);
+extern std::unique_ptr<state_machine> make_va_list_state_machine (logger *);
+extern std::unique_ptr<state_machine> make_fd_state_machine (logger *);
} // namespace ana
/* Internal interface to this file. */
-state_machine *
+std::unique_ptr<state_machine>
make_va_list_state_machine (logger *logger)
{
- return new va_list_state_machine (logger);
+ return std::make_unique<va_list_state_machine> (logger);
}
/* Handler for "__builtin_va_start". */