&iter_point,
emission_path,
pb.get_ext_state ());
- sm.on_stmt (&sm_ctxt, dst_point.get_supernode (), stmt);
+ sm.on_stmt (sm_ctxt, dst_point.get_supernode (), stmt);
// TODO: what about phi nodes?
}
}
m_old_state->m_checker_states[sm_idx],
m_new_state->m_checker_states[sm_idx],
m_path_ctxt);
- sm.on_condition (&sm_ctxt,
+ sm.on_condition (sm_ctxt,
(m_enode_for_diag
? m_enode_for_diag->get_supernode ()
: NULL),
m_old_state->m_checker_states[sm_idx],
m_new_state->m_checker_states[sm_idx],
m_path_ctxt);
- sm.on_bounded_ranges (&sm_ctxt,
+ sm.on_bounded_ranges (sm_ctxt,
(m_enode_for_diag
? m_enode_for_diag->get_supernode ()
: NULL),
m_old_state->m_checker_states[sm_idx],
m_new_state->m_checker_states[sm_idx],
m_path_ctxt);
- sm.on_phi (&sm_ctxt, m_enode_for_diag->get_supernode (), phi, rhs);
+ sm.on_phi (sm_ctxt, m_enode_for_diag->get_supernode (), phi, rhs);
}
}
unknown_side_effects);
/* Allow the state_machine to handle the stmt. */
- if (sm.on_stmt (&sm_ctxt, snode, stmt))
+ if (sm.on_stmt (sm_ctxt, snode, stmt))
unknown_side_effects = false;
}
return m_start;
}
- bool on_stmt (sm_context *sm_ctxt, const supernode *node,
+ bool on_stmt (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt) const final override;
- void on_condition (sm_context *sm_ctxt, const supernode *node,
+ void on_condition (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt, const svalue *lhs, const tree_code op,
const svalue *rhs) const final override;
bool on_socket (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const extrinsic_state &ext_state) const;
bool on_bind (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const extrinsic_state &ext_state) const;
bool on_listen (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const extrinsic_state &ext_state) const;
bool on_accept (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const extrinsic_state &ext_state) const;
bool on_connect (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const extrinsic_state &ext_state) const;
/* State for a constant file descriptor (>= 0) */
tree m_SOCK_DGRAM;
private:
- void on_open (sm_context *sm_ctxt, const supernode *node, const gimple *stmt,
+ void on_open (sm_context &sm_ctxt, const supernode *node, const gimple *stmt,
const gcall *call) const;
- void on_creat (sm_context *sm_ctxt, const supernode *node, const gimple *stmt,
+ void on_creat (sm_context &sm_ctxt, const supernode *node, const gimple *stmt,
const gcall *call) const;
- void on_close (sm_context *sm_ctxt, const supernode *node, const gimple *stmt,
+ void on_close (sm_context &sm_ctxt, const supernode *node, const gimple *stmt,
const gcall *call) const;
- void on_read (sm_context *sm_ctxt, const supernode *node, const gimple *stmt,
+ void on_read (sm_context &sm_ctxt, const supernode *node, const gimple *stmt,
const gcall *call, const tree callee_fndecl) const;
- void on_write (sm_context *sm_ctxt, const supernode *node, const gimple *stmt,
+ void on_write (sm_context &sm_ctxt, const supernode *node, const gimple *stmt,
const gcall *call, const tree callee_fndecl) const;
- void check_for_open_fd (sm_context *sm_ctxt, const supernode *node,
+ void check_for_open_fd (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt, const gcall *call,
const tree callee_fndecl,
enum access_directions access_fn) const;
- void make_valid_transitions_on_condition (sm_context *sm_ctxt,
+ void make_valid_transitions_on_condition (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const svalue *lhs) const;
- void make_invalid_transitions_on_condition (sm_context *sm_ctxt,
+ void make_invalid_transitions_on_condition (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const svalue *lhs) const;
- void check_for_fd_attrs (sm_context *sm_ctxt, const supernode *node,
+ void check_for_fd_attrs (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt, const gcall *call,
const tree callee_fndecl, const char *attr_name,
access_directions fd_attr_access_dir) const;
- void check_for_dup (sm_context *sm_ctxt, const supernode *node,
+ void check_for_dup (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt, const gcall *call, const tree callee_fndecl,
enum dup kind) const;
bool check_for_socket_fd (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const svalue *fd_sval,
const supernode *node,
state_t old_state,
bool *complained = NULL) const;
bool check_for_new_socket_fd (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const svalue *fd_sval,
const supernode *node,
state_t old_state,
}
bool
-fd_state_machine::on_stmt (sm_context *sm_ctxt, const supernode *node,
+fd_state_machine::on_stmt (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt) const
{
if (const gcall *call = dyn_cast<const gcall *> (stmt))
- if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
+ if (tree callee_fndecl = sm_ctxt.get_fndecl_for_call (call))
{
if (is_named_call_p (callee_fndecl, "open", call, 2))
{
void
fd_state_machine::check_for_fd_attrs (
- sm_context *sm_ctxt, const supernode *node, const gimple *stmt,
+ sm_context &sm_ctxt, const supernode *node, const gimple *stmt,
const gcall *call, const tree callee_fndecl, const char *attr_name,
access_directions fd_attr_access_dir) const
{
tree fndecl = callee_fndecl;
/* If call is recognized as a builtin known_function,
use that builtin's function_decl. */
- if (const region_model *old_model = sm_ctxt->get_old_region_model ())
+ if (const region_model *old_model = sm_ctxt.get_old_region_model ())
if (const builtin_known_function *builtin_kf
= old_model->get_builtin_kf (call))
fndecl = builtin_kf->builtin_decl ();
for (unsigned arg_idx = 0; arg_idx < gimple_call_num_args (call); arg_idx++)
{
tree arg = gimple_call_arg (call, arg_idx);
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- state_t state = sm_ctxt->get_state (stmt, arg);
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ state_t state = sm_ctxt.get_state (stmt, arg);
bool bit_set = bitmap_bit_p (argmap, arg_idx);
if (TREE_CODE (TREE_TYPE (arg)) != INTEGER_TYPE)
continue;
if (is_closed_fd_p (state))
{
- sm_ctxt->warn (node, stmt, arg,
- make_unique<fd_use_after_close>
- (*this, diag_arg,
- fndecl, attr_name,
- arg_idx));
+ sm_ctxt.warn (node, stmt, arg,
+ make_unique<fd_use_after_close>
+ (*this, diag_arg,
+ fndecl, attr_name,
+ arg_idx));
continue;
}
{
if (!is_constant_fd_p (state))
{
- sm_ctxt->warn (node, stmt, arg,
- make_unique<fd_use_without_check>
- (*this, diag_arg,
- fndecl, attr_name,
- arg_idx));
+ sm_ctxt.warn (node, stmt, arg,
+ make_unique<fd_use_without_check>
+ (*this, diag_arg,
+ fndecl, attr_name,
+ arg_idx));
continue;
}
}
if (is_writeonly_fd_p (state))
{
- sm_ctxt->warn (
+ sm_ctxt.warn (
node, stmt, arg,
make_unique<fd_access_mode_mismatch> (*this, diag_arg,
DIRS_WRITE,
if (is_readonly_fd_p (state))
{
- sm_ctxt->warn (
+ sm_ctxt.warn (
node, stmt, arg,
make_unique<fd_access_mode_mismatch> (*this, diag_arg,
DIRS_READ,
void
-fd_state_machine::on_open (sm_context *sm_ctxt, const supernode *node,
+fd_state_machine::on_open (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt, const gcall *call) const
{
tree lhs = gimple_call_lhs (call);
switch (mode)
{
case READ_ONLY:
- sm_ctxt->on_transition (node, stmt, lhs, m_start,
- m_unchecked_read_only);
+ sm_ctxt.on_transition (node, stmt, lhs, m_start,
+ m_unchecked_read_only);
break;
case WRITE_ONLY:
- sm_ctxt->on_transition (node, stmt, lhs, m_start,
- m_unchecked_write_only);
+ sm_ctxt.on_transition (node, stmt, lhs, m_start,
+ m_unchecked_write_only);
break;
default:
- sm_ctxt->on_transition (node, stmt, lhs, m_start,
- m_unchecked_read_write);
+ sm_ctxt.on_transition (node, stmt, lhs, m_start,
+ m_unchecked_read_write);
}
}
else
{
- sm_ctxt->warn (node, stmt, NULL_TREE,
- make_unique<fd_leak> (*this, NULL_TREE));
+ sm_ctxt.warn (node, stmt, NULL_TREE,
+ make_unique<fd_leak> (*this, NULL_TREE));
}
}
void
-fd_state_machine::on_creat (sm_context *sm_ctxt, const supernode *node,
+fd_state_machine::on_creat (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt, const gcall *call) const
{
tree lhs = gimple_call_lhs (call);
if (lhs)
- sm_ctxt->on_transition (node, stmt, lhs, m_start, m_unchecked_write_only);
+ sm_ctxt.on_transition (node, stmt, lhs, m_start, m_unchecked_write_only);
else
- sm_ctxt->warn (node, stmt, NULL_TREE,
- make_unique<fd_leak> (*this, NULL_TREE));
+ sm_ctxt.warn (node, stmt, NULL_TREE,
+ make_unique<fd_leak> (*this, NULL_TREE));
}
void
-fd_state_machine::check_for_dup (sm_context *sm_ctxt, const supernode *node,
+fd_state_machine::check_for_dup (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt, const gcall *call,
const tree callee_fndecl, enum dup kind) const
{
tree lhs = gimple_call_lhs (call);
tree arg_1 = gimple_call_arg (call, 0);
- state_t state_arg_1 = sm_ctxt->get_state (stmt, arg_1);
+ state_t state_arg_1 = sm_ctxt.get_state (stmt, arg_1);
if (state_arg_1 == m_stop)
return;
if (!(is_constant_fd_p (state_arg_1) || is_valid_fd_p (state_arg_1)
if (lhs)
{
if (is_constant_fd_p (state_arg_1) || state_arg_1 == m_start)
- sm_ctxt->set_next_state (stmt, lhs, m_unchecked_read_write);
+ sm_ctxt.set_next_state (stmt, lhs, m_unchecked_read_write);
else
- sm_ctxt->set_next_state (stmt, lhs,
- valid_to_unchecked_state (state_arg_1));
+ sm_ctxt.set_next_state (stmt, lhs,
+ valid_to_unchecked_state (state_arg_1));
}
break;
case DUP_2:
case DUP_3:
tree arg_2 = gimple_call_arg (call, 1);
- state_t state_arg_2 = sm_ctxt->get_state (stmt, arg_2);
- tree diag_arg_2 = sm_ctxt->get_diagnostic_tree (arg_2);
+ state_t state_arg_2 = sm_ctxt.get_state (stmt, arg_2);
+ tree diag_arg_2 = sm_ctxt.get_diagnostic_tree (arg_2);
if (state_arg_2 == m_stop)
return;
/* Check if -1 was passed as second argument to dup2. */
if (!(is_constant_fd_p (state_arg_2) || is_valid_fd_p (state_arg_2)
|| state_arg_2 == m_start))
{
- sm_ctxt->warn (
+ sm_ctxt.warn (
node, stmt, arg_2,
make_unique<fd_use_without_check> (*this, diag_arg_2,
callee_fndecl));
if (lhs)
{
if (is_constant_fd_p (state_arg_1) || state_arg_1 == m_start)
- sm_ctxt->set_next_state (stmt, lhs, m_unchecked_read_write);
+ sm_ctxt.set_next_state (stmt, lhs, m_unchecked_read_write);
else
- sm_ctxt->set_next_state (stmt, lhs,
- valid_to_unchecked_state (state_arg_1));
+ sm_ctxt.set_next_state (stmt, lhs,
+ valid_to_unchecked_state (state_arg_1));
}
break;
}
void
-fd_state_machine::on_close (sm_context *sm_ctxt, const supernode *node,
+fd_state_machine::on_close (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt, const gcall *call) const
{
tree arg = gimple_call_arg (call, 0);
- state_t state = sm_ctxt->get_state (stmt, arg);
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
-
- sm_ctxt->on_transition (node, stmt, arg, m_start, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_unchecked_read_write, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_unchecked_read_only, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_unchecked_write_only, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_valid_read_write, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_valid_read_only, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_valid_write_only, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_constant_fd, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_new_datagram_socket, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_new_stream_socket, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_new_unknown_socket, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_bound_datagram_socket, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_bound_stream_socket, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_bound_unknown_socket, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_listening_stream_socket, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_connected_stream_socket, m_closed);
+ state_t state = sm_ctxt.get_state (stmt, arg);
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+
+ sm_ctxt.on_transition (node, stmt, arg, m_start, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_unchecked_read_write, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_unchecked_read_only, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_unchecked_write_only, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_valid_read_write, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_valid_read_only, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_valid_write_only, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_constant_fd, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_new_datagram_socket, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_new_stream_socket, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_new_unknown_socket, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_bound_datagram_socket, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_bound_stream_socket, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_bound_unknown_socket, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_listening_stream_socket, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_connected_stream_socket, m_closed);
if (is_closed_fd_p (state))
{
- sm_ctxt->warn (node, stmt, arg,
- make_unique<fd_double_close> (*this, diag_arg));
- sm_ctxt->set_next_state (stmt, arg, m_stop);
+ sm_ctxt.warn (node, stmt, arg,
+ make_unique<fd_double_close> (*this, diag_arg));
+ sm_ctxt.set_next_state (stmt, arg, m_stop);
}
}
void
-fd_state_machine::on_read (sm_context *sm_ctxt, const supernode *node,
+fd_state_machine::on_read (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt, const gcall *call,
const tree callee_fndecl) const
{
check_for_open_fd (sm_ctxt, node, stmt, call, callee_fndecl, DIRS_READ);
}
void
-fd_state_machine::on_write (sm_context *sm_ctxt, const supernode *node,
+fd_state_machine::on_write (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt, const gcall *call,
const tree callee_fndecl) const
{
void
fd_state_machine::check_for_open_fd (
- sm_context *sm_ctxt, const supernode *node, const gimple *stmt,
+ sm_context &sm_ctxt, const supernode *node, const gimple *stmt,
const gcall *call, const tree callee_fndecl,
enum access_directions callee_fndecl_dir) const
{
tree arg = gimple_call_arg (call, 0);
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- state_t state = sm_ctxt->get_state (stmt, arg);
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ state_t state = sm_ctxt.get_state (stmt, arg);
if (is_closed_fd_p (state))
{
- sm_ctxt->warn (node, stmt, arg,
- make_unique<fd_use_after_close> (*this, diag_arg,
- callee_fndecl));
+ sm_ctxt.warn (node, stmt, arg,
+ make_unique<fd_use_after_close> (*this, diag_arg,
+ callee_fndecl));
}
else
|| state == m_bound_stream_socket
|| state == m_listening_stream_socket)
/* Complain about fncall on socket in wrong phase. */
- sm_ctxt->warn
+ sm_ctxt.warn
(node, stmt, arg,
make_unique<fd_phase_mismatch> (*this, diag_arg,
callee_fndecl,
|| state == m_stop))
{
if (!is_constant_fd_p (state))
- sm_ctxt->warn (
+ sm_ctxt.warn (
node, stmt, arg,
make_unique<fd_use_without_check> (*this, diag_arg,
callee_fndecl));
case DIRS_READ:
if (is_writeonly_fd_p (state))
{
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- sm_ctxt->warn (node, stmt, arg,
- make_unique<fd_access_mode_mismatch> (
- *this, diag_arg, DIRS_WRITE, callee_fndecl));
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ sm_ctxt.warn (node, stmt, arg,
+ make_unique<fd_access_mode_mismatch> (
+ *this, diag_arg, DIRS_WRITE, callee_fndecl));
}
break;
if (is_readonly_fd_p (state))
{
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- sm_ctxt->warn (node, stmt, arg,
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ sm_ctxt.warn (node, stmt, arg,
make_unique<fd_access_mode_mismatch> (
*this, diag_arg, DIRS_READ, callee_fndecl));
}
bool
fd_state_machine::on_socket (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const extrinsic_state &ext_state) const
{
const gcall *stmt = cd.get_call_stmt ();
const svalue *socket_type_sval = cd.get_arg_svalue (1);
state_machine::state_t new_state
= get_state_for_socket_type (socket_type_sval);
- sm_ctxt->on_transition (node, stmt, new_fd, m_start, new_state);
+ sm_ctxt.on_transition (node, stmt, new_fd, m_start, new_state);
model->set_value (cd.get_lhs_region (), new_fd, cd.get_ctxt ());
}
else
- sm_ctxt->warn (node, stmt, NULL_TREE,
- make_unique<fd_leak> (*this, NULL_TREE));
+ sm_ctxt.warn (node, stmt, NULL_TREE,
+ make_unique<fd_leak> (*this, NULL_TREE));
}
else
{
bool
fd_state_machine::check_for_socket_fd (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const svalue *fd_sval,
const supernode *node,
state_t old_state,
if (is_closed_fd_p (old_state))
{
- tree diag_arg = sm_ctxt->get_diagnostic_tree (fd_sval);
- sm_ctxt->warn
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (fd_sval);
+ sm_ctxt.warn
(node, stmt, fd_sval,
make_unique<fd_use_after_close> (*this, diag_arg,
cd.get_fndecl_for_call ()));
else if (is_unchecked_fd_p (old_state) || is_valid_fd_p (old_state))
{
/* Complain about non-socket. */
- tree diag_arg = sm_ctxt->get_diagnostic_tree (fd_sval);
- sm_ctxt->warn
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (fd_sval);
+ sm_ctxt.warn
(node, stmt, fd_sval,
make_unique<fd_type_mismatch> (*this, diag_arg,
cd.get_fndecl_for_call (),
}
else if (old_state == m_invalid)
{
- tree diag_arg = sm_ctxt->get_diagnostic_tree (fd_sval);
- sm_ctxt->warn
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (fd_sval);
+ sm_ctxt.warn
(node, stmt, fd_sval,
make_unique<fd_use_without_check> (*this, diag_arg,
cd.get_fndecl_for_call ()));
bool
fd_state_machine::check_for_new_socket_fd (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const svalue *fd_sval,
const supernode *node,
state_t old_state,
|| old_state == m_constant_fd))
{
/* Complain about "bind" or "connect" in wrong phase. */
- tree diag_arg = sm_ctxt->get_diagnostic_tree (fd_sval);
- sm_ctxt->warn
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (fd_sval);
+ sm_ctxt.warn
(node, cd.get_call_stmt (), fd_sval,
make_unique<fd_phase_mismatch> (*this, diag_arg,
cd.get_fndecl_for_call (),
{
/* If we were in the start state, assume we had a new socket. */
if (old_state == m_start)
- sm_ctxt->set_next_state (cd.get_call_stmt (), fd_sval,
- m_new_unknown_socket);
+ sm_ctxt.set_next_state (cd.get_call_stmt (), fd_sval,
+ m_new_unknown_socket);
}
/* Passing NULL as the address will lead to failure. */
bool
fd_state_machine::on_bind (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const extrinsic_state &ext_state) const
{
const gcall *stmt = cd.get_call_stmt ();
const supernode *node = sg->get_supernode_for_stmt (stmt);
const svalue *fd_sval = cd.get_arg_svalue (0);
region_model *model = cd.get_model ();
- state_t old_state = sm_ctxt->get_state (stmt, fd_sval);
+ state_t old_state = sm_ctxt.get_state (stmt, fd_sval);
if (!check_for_new_socket_fd (cd, successful, sm_ctxt,
fd_sval, node, old_state,
next_state = m_stop;
else
gcc_unreachable ();
- sm_ctxt->set_next_state (cd.get_call_stmt (), fd_sval, next_state);
+ sm_ctxt.set_next_state (cd.get_call_stmt (), fd_sval, next_state);
model->update_for_zero_return (cd, true);
}
else
bool
fd_state_machine::on_listen (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const extrinsic_state &ext_state) const
{
const gcall *stmt = cd.get_call_stmt ();
const supernode *node = sg->get_supernode_for_stmt (cd.get_call_stmt ());
const svalue *fd_sval = cd.get_arg_svalue (0);
region_model *model = cd.get_model ();
- state_t old_state = sm_ctxt->get_state (stmt, fd_sval);
+ state_t old_state = sm_ctxt.get_state (stmt, fd_sval);
/* We expect a stream socket that's had "bind" called on it. */
if (!check_for_socket_fd (cd, successful, sm_ctxt, fd_sval, node, old_state))
|| old_state == m_listening_stream_socket))
{
/* Complain about fncall on wrong type or in wrong phase. */
- tree diag_arg = sm_ctxt->get_diagnostic_tree (fd_sval);
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (fd_sval);
if (is_stream_socket_fd_p (old_state))
- sm_ctxt->warn
+ sm_ctxt.warn
(node, stmt, fd_sval,
make_unique<fd_phase_mismatch> (*this, diag_arg,
cd.get_fndecl_for_call (),
old_state,
EXPECTED_PHASE_CAN_LISTEN));
else
- sm_ctxt->warn
+ sm_ctxt.warn
(node, stmt, fd_sval,
make_unique<fd_type_mismatch> (*this, diag_arg,
cd.get_fndecl_for_call (),
if (successful)
{
model->update_for_zero_return (cd, true);
- sm_ctxt->set_next_state (cd.get_call_stmt (), fd_sval,
- m_listening_stream_socket);
+ sm_ctxt.set_next_state (cd.get_call_stmt (), fd_sval,
+ m_listening_stream_socket);
}
else
{
model->update_for_int_cst_return (cd, -1, true);
model->set_errno (cd);
if (old_state == m_start)
- sm_ctxt->set_next_state (cd.get_call_stmt (), fd_sval,
- m_bound_stream_socket);
+ sm_ctxt.set_next_state (cd.get_call_stmt (), fd_sval,
+ m_bound_stream_socket);
}
return true;
bool
fd_state_machine::on_accept (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const extrinsic_state &ext_state) const
{
const gcall *stmt = cd.get_call_stmt ();
const svalue *address_sval = cd.get_arg_svalue (1);
const svalue *len_ptr_sval = cd.get_arg_svalue (2);
region_model *model = cd.get_model ();
- state_t old_state = sm_ctxt->get_state (stmt, fd_sval);
+ state_t old_state = sm_ctxt.get_state (stmt, fd_sval);
if (!address_sval->all_zeroes_p ())
{
if (old_state == m_start || old_state == m_constant_fd)
/* If we were in the start state (or a constant), assume we had the
expected state. */
- sm_ctxt->set_next_state (cd.get_call_stmt (), fd_sval,
- m_listening_stream_socket);
+ sm_ctxt.set_next_state (cd.get_call_stmt (), fd_sval,
+ m_listening_stream_socket);
else if (old_state == m_stop)
{
/* No further complaints. */
else if (old_state != m_listening_stream_socket)
{
/* Complain about fncall on wrong type or in wrong phase. */
- tree diag_arg = sm_ctxt->get_diagnostic_tree (fd_sval);
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (fd_sval);
if (is_stream_socket_fd_p (old_state))
- sm_ctxt->warn
+ sm_ctxt.warn
(node, stmt, fd_sval,
make_unique<fd_phase_mismatch> (*this, diag_arg,
cd.get_fndecl_for_call (),
old_state,
EXPECTED_PHASE_CAN_ACCEPT));
else
- sm_ctxt->warn
+ sm_ctxt.warn
(node, stmt, fd_sval,
make_unique<fd_type_mismatch> (*this, diag_arg,
cd.get_fndecl_for_call (),
p);
if (!add_constraint_ge_zero (model, new_fd, cd.get_ctxt ()))
return false;
- sm_ctxt->on_transition (node, stmt, new_fd,
- m_start, m_connected_stream_socket);
+ sm_ctxt.on_transition (node, stmt, new_fd,
+ m_start, m_connected_stream_socket);
model->set_value (cd.get_lhs_region (), new_fd, cd.get_ctxt ());
}
else
- sm_ctxt->warn (node, stmt, NULL_TREE,
- make_unique<fd_leak> (*this, NULL_TREE));
+ sm_ctxt.warn (node, stmt, NULL_TREE,
+ make_unique<fd_leak> (*this, NULL_TREE));
}
else
{
bool
fd_state_machine::on_connect (const call_details &cd,
bool successful,
- sm_context *sm_ctxt,
+ sm_context &sm_ctxt,
const extrinsic_state &ext_state) const
{
const gcall *stmt = cd.get_call_stmt ();
const supernode *node = sg->get_supernode_for_stmt (stmt);
const svalue *fd_sval = cd.get_arg_svalue (0);
region_model *model = cd.get_model ();
- state_t old_state = sm_ctxt->get_state (stmt, fd_sval);
+ state_t old_state = sm_ctxt.get_state (stmt, fd_sval);
if (!check_for_new_socket_fd (cd, successful, sm_ctxt,
fd_sval, node, old_state,
next_state = m_stop;
else
gcc_unreachable ();
- sm_ctxt->set_next_state (cd.get_call_stmt (), fd_sval, next_state);
+ sm_ctxt.set_next_state (cd.get_call_stmt (), fd_sval, next_state);
}
else
{
}
void
-fd_state_machine::on_condition (sm_context *sm_ctxt, const supernode *node,
+fd_state_machine::on_condition (sm_context &sm_ctxt, const supernode *node,
const gimple *stmt, const svalue *lhs,
enum tree_code op, const svalue *rhs) const
{
}
void
-fd_state_machine::make_valid_transitions_on_condition (sm_context *sm_ctxt,
+fd_state_machine::make_valid_transitions_on_condition (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const svalue *lhs) const
{
- sm_ctxt->on_transition (node, stmt, lhs, m_unchecked_read_write,
- m_valid_read_write);
- sm_ctxt->on_transition (node, stmt, lhs, m_unchecked_read_only,
- m_valid_read_only);
- sm_ctxt->on_transition (node, stmt, lhs, m_unchecked_write_only,
- m_valid_write_only);
+ sm_ctxt.on_transition (node, stmt, lhs, m_unchecked_read_write,
+ m_valid_read_write);
+ sm_ctxt.on_transition (node, stmt, lhs, m_unchecked_read_only,
+ m_valid_read_only);
+ sm_ctxt.on_transition (node, stmt, lhs, m_unchecked_write_only,
+ m_valid_write_only);
}
void
fd_state_machine::make_invalid_transitions_on_condition (
- sm_context *sm_ctxt, const supernode *node, const gimple *stmt,
+ sm_context &sm_ctxt, const supernode *node, const gimple *stmt,
const svalue *lhs) const
{
- sm_ctxt->on_transition (node, stmt, lhs, m_unchecked_read_write, m_invalid);
- sm_ctxt->on_transition (node, stmt, lhs, m_unchecked_read_only, m_invalid);
- sm_ctxt->on_transition (node, stmt, lhs, m_unchecked_write_only, m_invalid);
+ sm_ctxt.on_transition (node, stmt, lhs, m_unchecked_read_write, m_invalid);
+ sm_ctxt.on_transition (node, stmt, lhs, m_unchecked_read_only, m_invalid);
+ sm_ctxt.on_transition (node, stmt, lhs, m_unchecked_write_only, m_invalid);
}
bool
return true;
}
- return fd_sm->on_socket (cd, m_success, sm_ctxt.get (), *ext_state);
+ return fd_sm->on_socket (cd, m_success, *(sm_ctxt.get ()), *ext_state);
}
};
cd.set_any_lhs_with_defaults ();
return true;
}
- return fd_sm->on_bind (cd, m_success, sm_ctxt.get (), *ext_state);
+ return fd_sm->on_bind (cd, m_success, *sm_ctxt.get (), *ext_state);
}
};
return true;
}
- return fd_sm->on_listen (cd, m_success, sm_ctxt.get (), *ext_state);
+ return fd_sm->on_listen (cd, m_success, *sm_ctxt.get (), *ext_state);
}
};
return true;
}
- return fd_sm->on_accept (cd, m_success, sm_ctxt.get (), *ext_state);
+ return fd_sm->on_accept (cd, m_success, *sm_ctxt.get (), *ext_state);
}
};
return true;
}
- return fd_sm->on_connect (cd, m_success, sm_ctxt.get (), *ext_state);
+ return fd_sm->on_connect (cd, m_success, *sm_ctxt.get (), *ext_state);
}
};
return m_start;
}
- bool on_stmt (sm_context *sm_ctxt,
+ bool on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const final override;
- void on_condition (sm_context *sm_ctxt,
+ void on_condition (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const svalue *lhs,
/* Implementation of state_machine::on_stmt vfunc for fileptr_state_machine. */
bool
-fileptr_state_machine::on_stmt (sm_context *sm_ctxt,
+fileptr_state_machine::on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const
{
if (const gcall *call = dyn_cast <const gcall *> (stmt))
- if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
+ if (tree callee_fndecl = sm_ctxt.get_fndecl_for_call (call))
{
if (is_named_call_p (callee_fndecl, "fopen", call, 2))
{
tree lhs = gimple_call_lhs (call);
if (lhs)
- sm_ctxt->on_transition (node, stmt, lhs, m_start, m_unchecked);
+ sm_ctxt.on_transition (node, stmt, lhs, m_start, m_unchecked);
else
{
/* TODO: report leak. */
{
tree arg = gimple_call_arg (call, 0);
- sm_ctxt->on_transition (node, stmt, arg, m_start, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_start, m_closed);
// TODO: is it safe to call fclose (NULL) ?
- sm_ctxt->on_transition (node, stmt, arg, m_unchecked, m_closed);
- sm_ctxt->on_transition (node, stmt, arg, m_null, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_unchecked, m_closed);
+ sm_ctxt.on_transition (node, stmt, arg, m_null, m_closed);
- sm_ctxt->on_transition (node, stmt , arg, m_nonnull, m_closed);
+ sm_ctxt.on_transition (node, stmt , arg, m_nonnull, m_closed);
- if (sm_ctxt->get_state (stmt, arg) == m_closed)
+ if (sm_ctxt.get_state (stmt, arg) == m_closed)
{
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- sm_ctxt->warn (node, stmt, arg,
- make_unique<double_fclose> (*this, diag_arg));
- sm_ctxt->set_next_state (stmt, arg, m_stop);
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ sm_ctxt.warn (node, stmt, arg,
+ make_unique<double_fclose> (*this, diag_arg));
+ sm_ctxt.set_next_state (stmt, arg, m_stop);
}
return true;
}
Potentially transition state 'unchecked' to 'nonnull' or to 'null'. */
void
-fileptr_state_machine::on_condition (sm_context *sm_ctxt,
+fileptr_state_machine::on_condition (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const svalue *lhs,
if (op == NE_EXPR)
{
log ("got 'ARG != 0' match");
- sm_ctxt->on_transition (node, stmt,
- lhs, m_unchecked, m_nonnull);
+ sm_ctxt.on_transition (node, stmt,
+ lhs, m_unchecked, m_nonnull);
}
else if (op == EQ_EXPR)
{
log ("got 'ARG == 0' match");
- sm_ctxt->on_transition (node, stmt,
- lhs, m_unchecked, m_null);
+ sm_ctxt.on_transition (node, stmt,
+ lhs, m_unchecked, m_null);
}
}
return m_start;
}
- bool on_stmt (sm_context *sm_ctxt,
+ bool on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const final override;
- void on_phi (sm_context *sm_ctxt,
+ void on_phi (sm_context &sm_ctxt,
const supernode *node,
const gphi *phi,
tree rhs) const final override;
- void on_condition (sm_context *sm_ctxt,
+ void on_condition (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const svalue *lhs,
static bool unaffected_by_call_p (tree fndecl);
- void maybe_assume_non_null (sm_context *sm_ctxt,
+ void maybe_assume_non_null (sm_context &sm_ctxt,
tree ptr,
const gimple *stmt) const;
get_or_create_assumed_non_null_state_for_frame (const frame_region *frame);
void
- maybe_complain_about_deref_before_check (sm_context *sm_ctxt,
+ maybe_complain_about_deref_before_check (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const assumed_non_null_state *,
tree ptr) const;
- void on_allocator_call (sm_context *sm_ctxt,
+ void on_allocator_call (sm_context &sm_ctxt,
const gcall *call,
const deallocator_set *deallocators,
bool returns_nonnull = false) const;
- void handle_free_of_non_heap (sm_context *sm_ctxt,
+ void handle_free_of_non_heap (sm_context &sm_ctxt,
const supernode *node,
const gcall *call,
tree arg,
const deallocator *d) const;
- void on_deallocator_call (sm_context *sm_ctxt,
+ void on_deallocator_call (sm_context &sm_ctxt,
const supernode *node,
const gcall *call,
const deallocator *d,
unsigned argno) const;
- void on_realloc_call (sm_context *sm_ctxt,
+ void on_realloc_call (sm_context &sm_ctxt,
const supernode *node,
const gcall *call) const;
- void on_zero_assignment (sm_context *sm_ctxt,
+ void on_zero_assignment (sm_context &sm_ctxt,
const gimple *stmt,
tree lhs) const;
state for the current frame. */
void
-malloc_state_machine::maybe_assume_non_null (sm_context *sm_ctxt,
+malloc_state_machine::maybe_assume_non_null (sm_context &sm_ctxt,
tree ptr,
const gimple *stmt) const
{
- const region_model *old_model = sm_ctxt->get_old_region_model ();
+ const region_model *old_model = sm_ctxt.get_old_region_model ();
if (!old_model)
return;
state_t next_state
= mut_this->get_or_create_assumed_non_null_state_for_frame
(old_model->get_current_frame ());
- sm_ctxt->set_next_state (stmt, ptr, next_state);
+ sm_ctxt.set_next_state (stmt, ptr, next_state);
}
}
/* Implementation of state_machine::on_stmt vfunc for malloc_state_machine. */
bool
-malloc_state_machine::on_stmt (sm_context *sm_ctxt,
+malloc_state_machine::on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const
{
if (const gcall *call = dyn_cast <const gcall *> (stmt))
- if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
+ if (tree callee_fndecl = sm_ctxt.get_fndecl_for_call (call))
{
if (known_allocator_p (callee_fndecl, call))
{
{
tree lhs = gimple_call_lhs (call);
if (lhs)
- sm_ctxt->on_transition (node, stmt, lhs, m_start, m_non_heap);
+ sm_ctxt.on_transition (node, stmt, lhs, m_start, m_non_heap);
return true;
}
tree fndecl = callee_fndecl;
/* If call is recognized as a builtin known_function, use that
builtin's function_decl. */
- if (const region_model *old_model = sm_ctxt->get_old_region_model ())
+ if (const region_model *old_model = sm_ctxt.get_old_region_model ())
if (const builtin_known_function *builtin_kf
= old_model->get_builtin_kf (call))
fndecl = builtin_kf->builtin_decl ();
if (bitmap_empty_p (nonnull_args)
|| bitmap_bit_p (nonnull_args, i))
{
- state_t state = sm_ctxt->get_state (stmt, arg);
+ state_t state = sm_ctxt.get_state (stmt, arg);
/* Can't use a switch as the states are non-const. */
/* Do use the fndecl that caused the warning so that the
misused attributes are printed and the user not
confused. */
if (unchecked_p (state))
{
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- sm_ctxt->warn (node, stmt, arg,
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ sm_ctxt.warn (node, stmt, arg,
make_unique<possible_null_arg>
(*this, diag_arg, fndecl, i));
const allocation_state *astate
= as_a_allocation_state (state);
- sm_ctxt->set_next_state (stmt, arg,
+ sm_ctxt.set_next_state (stmt, arg,
astate->get_nonnull ());
}
else if (state == m_null)
{
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- sm_ctxt->warn (node, stmt, arg,
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ sm_ctxt.warn (node, stmt, arg,
make_unique<null_arg>
(*this, diag_arg, fndecl, i));
- sm_ctxt->set_next_state (stmt, arg, m_stop);
+ sm_ctxt.set_next_state (stmt, arg, m_stop);
}
else if (state == m_start)
maybe_assume_non_null (sm_ctxt, arg, stmt);
&& any_pointer_p (rhs)
&& zerop (rhs))
{
- state_t state = sm_ctxt->get_state (stmt, lhs);
+ state_t state = sm_ctxt.get_state (stmt, lhs);
if (assumed_non_null_p (state))
maybe_complain_about_deref_before_check
(sm_ctxt, node,
}
}
- if (tree lhs = sm_ctxt->is_zero_assignment (stmt))
+ if (tree lhs = sm_ctxt.is_zero_assignment (stmt))
if (any_pointer_p (lhs))
on_zero_assignment (sm_ctxt, stmt,lhs);
{
tree arg = TREE_OPERAND (op, 0);
- state_t state = sm_ctxt->get_state (stmt, arg);
+ state_t state = sm_ctxt.get_state (stmt, arg);
if (state == m_start)
maybe_assume_non_null (sm_ctxt, arg, stmt);
else if (unchecked_p (state))
{
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- sm_ctxt->warn (node, stmt, arg,
- make_unique<possible_null_deref> (*this,
- diag_arg));
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ sm_ctxt.warn (node, stmt, arg,
+ make_unique<possible_null_deref> (*this,
+ diag_arg));
const allocation_state *astate = as_a_allocation_state (state);
- sm_ctxt->set_next_state (stmt, arg, astate->get_nonnull ());
+ sm_ctxt.set_next_state (stmt, arg, astate->get_nonnull ());
}
else if (state == m_null)
{
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- sm_ctxt->warn (node, stmt, arg,
- make_unique<null_deref> (*this, diag_arg));
- sm_ctxt->set_next_state (stmt, arg, m_stop);
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ sm_ctxt.warn (node, stmt, arg,
+ make_unique<null_deref> (*this, diag_arg));
+ sm_ctxt.set_next_state (stmt, arg, m_stop);
}
else if (freed_p (state))
{
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
const allocation_state *astate = as_a_allocation_state (state);
- sm_ctxt->warn (node, stmt, arg,
- make_unique<use_after_free>
- (*this, diag_arg, astate->m_deallocator));
- sm_ctxt->set_next_state (stmt, arg, m_stop);
+ sm_ctxt.warn (node, stmt, arg,
+ make_unique<use_after_free>
+ (*this, diag_arg, astate->m_deallocator));
+ sm_ctxt.set_next_state (stmt, arg, m_stop);
}
}
}
void
malloc_state_machine::
-maybe_complain_about_deref_before_check (sm_context *sm_ctxt,
+maybe_complain_about_deref_before_check (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const assumed_non_null_state *state,
tree ptr) const
{
- const region_model *model = sm_ctxt->get_old_region_model ();
+ const region_model *model = sm_ctxt.get_old_region_model ();
if (!model)
return;
return;
}
- tree diag_ptr = sm_ctxt->get_diagnostic_tree (ptr);
+ tree diag_ptr = sm_ctxt.get_diagnostic_tree (ptr);
if (diag_ptr)
- sm_ctxt->warn
+ sm_ctxt.warn
(node, stmt, ptr,
make_unique<deref_before_check> (*this, diag_ptr));
- sm_ctxt->set_next_state (stmt, ptr, m_stop);
+ sm_ctxt.set_next_state (stmt, ptr, m_stop);
}
/* Handle a call to an allocator.
__attribute__((returns_nonnull)). */
void
-malloc_state_machine::on_allocator_call (sm_context *sm_ctxt,
+malloc_state_machine::on_allocator_call (sm_context &sm_ctxt,
const gcall *call,
const deallocator_set *deallocators,
bool returns_nonnull) const
tree lhs = gimple_call_lhs (call);
if (lhs)
{
- if (sm_ctxt->get_state (call, lhs) == m_start)
- sm_ctxt->set_next_state (call, lhs,
- (returns_nonnull
- ? deallocators->m_nonnull
- : deallocators->m_unchecked));
+ if (sm_ctxt.get_state (call, lhs) == m_start)
+ sm_ctxt.set_next_state (call, lhs,
+ (returns_nonnull
+ ? deallocators->m_nonnull
+ : deallocators->m_unchecked));
}
else
{
non-heap -> stop, with warning. */
void
-malloc_state_machine::handle_free_of_non_heap (sm_context *sm_ctxt,
+malloc_state_machine::handle_free_of_non_heap (sm_context &sm_ctxt,
const supernode *node,
const gcall *call,
tree arg,
const deallocator *d) const
{
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
const region *freed_reg = NULL;
- if (const program_state *old_state = sm_ctxt->get_old_program_state ())
+ if (const program_state *old_state = sm_ctxt.get_old_program_state ())
{
const region_model *old_model = old_state->m_region_model;
const svalue *ptr_sval = old_model->get_rvalue (arg, NULL);
freed_reg = old_model->deref_rvalue (ptr_sval, arg, NULL);
}
- sm_ctxt->warn (node, call, arg,
- make_unique<free_of_non_heap>
- (*this, diag_arg, freed_reg, d->m_name));
- sm_ctxt->set_next_state (call, arg, m_stop);
+ sm_ctxt.warn (node, call, arg,
+ make_unique<free_of_non_heap>
+ (*this, diag_arg, freed_reg, d->m_name));
+ sm_ctxt.set_next_state (call, arg, m_stop);
}
void
-malloc_state_machine::on_deallocator_call (sm_context *sm_ctxt,
+malloc_state_machine::on_deallocator_call (sm_context &sm_ctxt,
const supernode *node,
const gcall *call,
const deallocator *d,
return;
tree arg = gimple_call_arg (call, argno);
- state_t state = sm_ctxt->get_state (call, arg);
+ state_t state = sm_ctxt.get_state (call, arg);
/* start/assumed_non_null/unchecked/nonnull -> freed. */
if (state == m_start || assumed_non_null_p (state))
- sm_ctxt->set_next_state (call, arg, d->m_freed);
+ sm_ctxt.set_next_state (call, arg, d->m_freed);
else if (unchecked_p (state) || nonnull_p (state))
{
const allocation_state *astate = as_a_allocation_state (state);
if (!astate->m_deallocators->contains_p (d))
{
/* Wrong allocator. */
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- sm_ctxt->warn (node, call, arg,
- make_unique<mismatching_deallocation>
- (*this, diag_arg,
- astate->m_deallocators,
- d));
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ sm_ctxt.warn (node, call, arg,
+ make_unique<mismatching_deallocation>
+ (*this, diag_arg,
+ astate->m_deallocators,
+ d));
}
- sm_ctxt->set_next_state (call, arg, d->m_freed);
+ sm_ctxt.set_next_state (call, arg, d->m_freed);
}
/* Keep state "null" as-is, rather than transitioning to "freed";
else if (state == d->m_freed)
{
/* freed -> stop, with warning. */
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- sm_ctxt->warn (node, call, arg,
- make_unique<double_free> (*this, diag_arg, d->m_name));
- sm_ctxt->set_next_state (call, arg, m_stop);
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ sm_ctxt.warn (node, call, arg,
+ make_unique<double_free> (*this, diag_arg, d->m_name));
+ sm_ctxt.set_next_state (call, arg, m_stop);
}
else if (state == m_non_heap)
{
when the state is bifurcated). */
void
-malloc_state_machine::on_realloc_call (sm_context *sm_ctxt,
+malloc_state_machine::on_realloc_call (sm_context &sm_ctxt,
const supernode *node,
const gcall *call) const
{
tree arg = gimple_call_arg (call, argno);
- state_t state = sm_ctxt->get_state (call, arg);
+ state_t state = sm_ctxt.get_state (call, arg);
if (unchecked_p (state) || nonnull_p (state))
{
if (!astate->m_deallocators->contains_p (&m_free.m_deallocator))
{
/* Wrong allocator. */
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- sm_ctxt->warn (node, call, arg,
- make_unique<mismatching_deallocation>
- (*this, diag_arg,
- astate->m_deallocators, d));
- sm_ctxt->set_next_state (call, arg, m_stop);
- if (path_context *path_ctxt = sm_ctxt->get_path_context ())
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ sm_ctxt.warn (node, call, arg,
+ make_unique<mismatching_deallocation>
+ (*this, diag_arg,
+ astate->m_deallocators, d));
+ sm_ctxt.set_next_state (call, arg, m_stop);
+ if (path_context *path_ctxt = sm_ctxt.get_path_context ())
path_ctxt->terminate_path ();
}
}
else if (state == m_free.m_deallocator.m_freed)
{
/* freed -> stop, with warning. */
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- sm_ctxt->warn (node, call, arg,
- make_unique<double_free> (*this, diag_arg, "free"));
- sm_ctxt->set_next_state (call, arg, m_stop);
- if (path_context *path_ctxt = sm_ctxt->get_path_context ())
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ sm_ctxt.warn (node, call, arg,
+ make_unique<double_free> (*this, diag_arg, "free"));
+ sm_ctxt.set_next_state (call, arg, m_stop);
+ if (path_context *path_ctxt = sm_ctxt.get_path_context ())
path_ctxt->terminate_path ();
}
else if (state == m_non_heap)
{
/* non-heap -> stop, with warning. */
handle_free_of_non_heap (sm_ctxt, node, call, arg, d);
- if (path_context *path_ctxt = sm_ctxt->get_path_context ())
+ if (path_context *path_ctxt = sm_ctxt.get_path_context ())
path_ctxt->terminate_path ();
}
}
/* Implementation of state_machine::on_phi vfunc for malloc_state_machine. */
void
-malloc_state_machine::on_phi (sm_context *sm_ctxt,
+malloc_state_machine::on_phi (sm_context &sm_ctxt,
const supernode *node ATTRIBUTE_UNUSED,
const gphi *phi,
tree rhs) const
Potentially transition state 'unchecked' to 'nonnull' or to 'null'. */
void
-malloc_state_machine::on_condition (sm_context *sm_ctxt,
+malloc_state_machine::on_condition (sm_context &sm_ctxt,
const supernode *node ATTRIBUTE_UNUSED,
const gimple *stmt,
const svalue *lhs,
if (op == NE_EXPR)
{
log ("got 'ARG != 0' match");
- state_t s = sm_ctxt->get_state (stmt, lhs);
+ state_t s = sm_ctxt.get_state (stmt, lhs);
if (unchecked_p (s))
{
const allocation_state *astate = as_a_allocation_state (s);
- sm_ctxt->set_next_state (stmt, lhs, astate->get_nonnull ());
+ sm_ctxt.set_next_state (stmt, lhs, astate->get_nonnull ());
}
}
else if (op == EQ_EXPR)
{
log ("got 'ARG == 0' match");
- state_t s = sm_ctxt->get_state (stmt, lhs);
+ state_t s = sm_ctxt.get_state (stmt, lhs);
if (unchecked_p (s))
- sm_ctxt->set_next_state (stmt, lhs, m_null);
+ sm_ctxt.set_next_state (stmt, lhs, m_null);
}
}
assign zero to LHS. */
void
-malloc_state_machine::on_zero_assignment (sm_context *sm_ctxt,
+malloc_state_machine::on_zero_assignment (sm_context &sm_ctxt,
const gimple *stmt,
tree lhs) const
{
- state_t s = sm_ctxt->get_state (stmt, lhs);
+ state_t s = sm_ctxt.get_state (stmt, lhs);
enum resource_state rs = get_rs (s);
if (rs == RS_START
|| rs == RS_UNCHECKED
|| rs == RS_NONNULL
|| rs == RS_FREED)
- sm_ctxt->set_next_state (stmt, lhs, m_null);
+ sm_ctxt.set_next_state (stmt, lhs, m_null);
}
/* Special-case hook for handling realloc, for the "success with move to
bool inherited_state_p () const final override { return false; }
- bool on_stmt (sm_context *sm_ctxt,
+ bool on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const final override;
- void on_condition (sm_context *sm_ctxt,
+ void on_condition (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const svalue *lhs,
}
bool
-pattern_test_state_machine::on_stmt (sm_context *sm_ctxt ATTRIBUTE_UNUSED,
+pattern_test_state_machine::on_stmt (sm_context &sm_ctxt ATTRIBUTE_UNUSED,
const supernode *node ATTRIBUTE_UNUSED,
const gimple *stmt ATTRIBUTE_UNUSED) const
{
constant. */
void
-pattern_test_state_machine::on_condition (sm_context *sm_ctxt,
+pattern_test_state_machine::on_condition (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const svalue *lhs,
if (!rhs_cst)
return;
- if (tree lhs_expr = sm_ctxt->get_diagnostic_tree (lhs))
+ if (tree lhs_expr = sm_ctxt.get_diagnostic_tree (lhs))
{
- sm_ctxt->warn (node, stmt, lhs_expr,
- make_unique<pattern_match> (lhs_expr, op, rhs_cst));
+ sm_ctxt.warn (node, stmt, lhs_expr,
+ make_unique<pattern_match> (lhs_expr, op, rhs_cst));
}
}
bool inherited_state_p () const final override { return true; }
- bool on_stmt (sm_context *sm_ctxt,
+ bool on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const final override;
state_t m_stop;
private:
- void warn_for_any_exposure (sm_context *sm_ctxt,
+ void warn_for_any_exposure (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
tree arg) const;
state. */
void
-sensitive_state_machine::warn_for_any_exposure (sm_context *sm_ctxt,
+sensitive_state_machine::warn_for_any_exposure (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
tree arg) const
{
- if (sm_ctxt->get_state (stmt, arg) == m_sensitive)
+ if (sm_ctxt.get_state (stmt, arg) == m_sensitive)
{
- tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- sm_ctxt->warn (node, stmt, arg,
- make_unique<exposure_through_output_file> (*this,
- diag_arg));
+ tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
+ sm_ctxt.warn (node, stmt, arg,
+ make_unique<exposure_through_output_file> (*this,
+ diag_arg));
}
}
sensitive_state_machine. */
bool
-sensitive_state_machine::on_stmt (sm_context *sm_ctxt,
+sensitive_state_machine::on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const
{
if (const gcall *call = dyn_cast <const gcall *> (stmt))
- if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
+ if (tree callee_fndecl = sm_ctxt.get_fndecl_for_call (call))
{
if (is_named_call_p (callee_fndecl, "getpass", call, 1))
{
tree lhs = gimple_call_lhs (call);
if (lhs)
- sm_ctxt->on_transition (node, stmt, lhs, m_start, m_sensitive);
+ sm_ctxt.on_transition (node, stmt, lhs, m_start, m_sensitive);
return true;
}
else if (is_named_call_p (callee_fndecl, "fprintf")
bool inherited_state_p () const final override { return false; }
- bool on_stmt (sm_context *sm_ctxt,
+ bool on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const final override;
/* Implementation of state_machine::on_stmt vfunc for signal_state_machine. */
bool
-signal_state_machine::on_stmt (sm_context *sm_ctxt,
+signal_state_machine::on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const
{
- const state_t global_state = sm_ctxt->get_global_state ();
+ const state_t global_state = sm_ctxt.get_global_state ();
if (global_state == m_start)
{
if (const gcall *call = dyn_cast <const gcall *> (stmt))
- if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
+ if (tree callee_fndecl = sm_ctxt.get_fndecl_for_call (call))
if (is_named_call_p (callee_fndecl, "signal", call, 2)
|| is_std_named_call_p (callee_fndecl, "signal", call, 2))
{
{
tree fndecl = TREE_OPERAND (handler, 0);
register_signal_handler rsh (*this, fndecl);
- sm_ctxt->on_custom_transition (&rsh);
+ sm_ctxt.on_custom_transition (&rsh);
}
}
}
else if (global_state == m_in_signal_handler)
{
if (const gcall *call = dyn_cast <const gcall *> (stmt))
- if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
+ if (tree callee_fndecl = sm_ctxt.get_fndecl_for_call (call))
if (signal_unsafe_p (callee_fndecl))
- if (sm_ctxt->get_global_state () == m_in_signal_handler)
- sm_ctxt->warn (node, stmt, NULL_TREE,
- make_unique<signal_unsafe_call>
- (*this, call, callee_fndecl));
+ if (sm_ctxt.get_global_state () == m_in_signal_handler)
+ sm_ctxt.warn (node, stmt, NULL_TREE,
+ make_unique<signal_unsafe_call>
+ (*this, call, callee_fndecl));
}
return false;
return true;
}
- bool on_stmt (sm_context *sm_ctxt,
+ bool on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const final override;
- void on_condition (sm_context *sm_ctxt,
+ void on_condition (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const svalue *lhs,
enum tree_code op,
const svalue *rhs) const final override;
- void on_bounded_ranges (sm_context *sm_ctxt,
+ void on_bounded_ranges (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const svalue &sval,
state_t combine_states (state_t s0, state_t s1) const;
private:
- void check_control_flow_arg_for_taint (sm_context *sm_ctxt,
+ void check_control_flow_arg_for_taint (sm_context &sm_ctxt,
const gimple *stmt,
tree expr) const;
- void check_for_tainted_size_arg (sm_context *sm_ctxt,
+ void check_for_tainted_size_arg (sm_context &sm_ctxt,
const supernode *node,
const gcall *call,
tree callee_fndecl) const;
- void check_for_tainted_divisor (sm_context *sm_ctxt,
+ void check_for_tainted_divisor (sm_context &sm_ctxt,
const supernode *node,
const gassign *assign) const;
/* Implementation of state_machine::on_stmt vfunc for taint_state_machine. */
bool
-taint_state_machine::on_stmt (sm_context *sm_ctxt,
+taint_state_machine::on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const
{
if (const gcall *call = dyn_cast <const gcall *> (stmt))
- if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
+ if (tree callee_fndecl = sm_ctxt.get_fndecl_for_call (call))
{
if (is_named_call_p (callee_fndecl, "fread", call, 4))
{
tree arg = gimple_call_arg (call, 0);
- sm_ctxt->on_transition (node, stmt, arg, m_start, m_tainted);
+ sm_ctxt.on_transition (node, stmt, arg, m_start, m_tainted);
/* Dereference an ADDR_EXPR. */
// TODO: should the engine do this?
if (TREE_CODE (arg) == ADDR_EXPR)
- sm_ctxt->on_transition (node, stmt, TREE_OPERAND (arg, 0),
- m_start, m_tainted);
+ sm_ctxt.on_transition (node, stmt, TREE_OPERAND (arg, 0),
+ m_start, m_tainted);
return true;
}
/* External function with "access" attribute. */
- if (sm_ctxt->unknown_side_effects_p ())
+ if (sm_ctxt.unknown_side_effects_p ())
check_for_tainted_size_arg (sm_ctxt, node, call, callee_fndecl);
if (is_assertion_failure_handler_p (callee_fndecl)
- && sm_ctxt->get_global_state () == m_tainted_control_flow)
+ && sm_ctxt.get_global_state () == m_tainted_control_flow)
{
- sm_ctxt->warn (node, call, NULL_TREE,
- make_unique<tainted_assertion> (*this, NULL_TREE,
- callee_fndecl));
+ sm_ctxt.warn (node, call, NULL_TREE,
+ make_unique<tainted_assertion> (*this, NULL_TREE,
+ callee_fndecl));
}
}
// TODO: ...etc; many other sources of untrusted data
/* Reset the state of "tainted-control-flow" before each
control flow statement, so that only the last one before
an assertion-failure-handler counts. */
- sm_ctxt->set_global_state (m_start);
+ sm_ctxt.set_global_state (m_start);
check_control_flow_arg_for_taint (sm_ctxt, cond, gimple_cond_lhs (cond));
check_control_flow_arg_for_taint (sm_ctxt, cond, gimple_cond_rhs (cond));
}
/* Reset the state of "tainted-control-flow" before each
control flow statement, so that only the last one before
an assertion-failure-handler counts. */
- sm_ctxt->set_global_state (m_start);
+ sm_ctxt.set_global_state (m_start);
check_control_flow_arg_for_taint (sm_ctxt, switch_,
gimple_switch_index (switch_));
}
to call an assertion-failure-handler. */
void
-taint_state_machine::check_control_flow_arg_for_taint (sm_context *sm_ctxt,
+taint_state_machine::check_control_flow_arg_for_taint (sm_context &sm_ctxt,
const gimple *stmt,
tree expr) const
{
- const region_model *old_model = sm_ctxt->get_old_region_model ();
+ const region_model *old_model = sm_ctxt.get_old_region_model ();
const svalue *sval = old_model->get_rvalue (expr, NULL);
- state_t state = sm_ctxt->get_state (stmt, sval);
+ state_t state = sm_ctxt.get_state (stmt, sval);
enum bounds b;
if (get_taint (state, TREE_TYPE (expr), &b))
- sm_ctxt->set_global_state (m_tainted_control_flow);
+ sm_ctxt.set_global_state (m_tainted_control_flow);
}
/* Implementation of state_machine::on_condition vfunc for taint_state_machine.
and states 'has_ub' and 'has_lb' to 'stop'. */
void
-taint_state_machine::on_condition (sm_context *sm_ctxt,
+taint_state_machine::on_condition (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
const svalue *lhs,
// TODO: warn about this
if (get_logger ())
get_logger ()->log ("comparison against UNKNOWN; removing all taint");
- sm_ctxt->clear_all_per_svalue_state ();
+ sm_ctxt.clear_all_per_svalue_state ();
return;
}
/* (LHS >= RHS) or (LHS > RHS)
LHS gains a lower bound
RHS gains an upper bound. */
- sm_ctxt->on_transition (node, stmt, lhs, m_tainted,
- m_has_lb);
- sm_ctxt->on_transition (node, stmt, lhs, m_has_ub,
- m_stop);
- sm_ctxt->on_transition (node, stmt, rhs, m_tainted,
- m_has_ub);
- sm_ctxt->on_transition (node, stmt, rhs, m_has_lb,
- m_stop);
+ sm_ctxt.on_transition (node, stmt, lhs, m_tainted, m_has_lb);
+ sm_ctxt.on_transition (node, stmt, lhs, m_has_ub, m_stop);
+ sm_ctxt.on_transition (node, stmt, rhs, m_tainted, m_has_ub);
+ sm_ctxt.on_transition (node, stmt, rhs, m_has_lb, m_stop);
}
break;
case LE_EXPR:
from the old state to has_lb, then a transition from
the old state *again* to has_ub). */
state_t old_state
- = sm_ctxt->get_state (stmt, inner_lhs);
+ = sm_ctxt.get_state (stmt, inner_lhs);
if (old_state == m_tainted
|| old_state == m_has_lb
|| old_state == m_has_ub)
- sm_ctxt->set_next_state (stmt, inner_lhs, m_stop);
+ sm_ctxt.set_next_state (stmt, inner_lhs, m_stop);
return;
}
}
/* (LHS <= RHS) or (LHS < RHS)
LHS gains an upper bound
RHS gains a lower bound. */
- sm_ctxt->on_transition (node, stmt, lhs, m_tainted,
- m_has_ub);
- sm_ctxt->on_transition (node, stmt, lhs, m_has_lb,
- m_stop);
- sm_ctxt->on_transition (node, stmt, rhs, m_tainted,
- m_has_lb);
- sm_ctxt->on_transition (node, stmt, rhs, m_has_ub,
- m_stop);
+ sm_ctxt.on_transition (node, stmt, lhs, m_tainted, m_has_ub);
+ sm_ctxt.on_transition (node, stmt, lhs, m_has_lb, m_stop);
+ sm_ctxt.on_transition (node, stmt, rhs, m_tainted, m_has_lb);
+ sm_ctxt.on_transition (node, stmt, rhs, m_has_ub, m_stop);
}
break;
default:
and states 'has_ub' and 'has_lb' to 'stop'. */
void
-taint_state_machine::on_bounded_ranges (sm_context *sm_ctxt,
+taint_state_machine::on_bounded_ranges (sm_context &sm_ctxt,
const supernode *,
const gimple *stmt,
const svalue &sval,
/* We have new bounds from the ranges; combine them with any
existing bounds on SVAL. */
- state_t old_state = sm_ctxt->get_state (stmt, &sval);
+ state_t old_state = sm_ctxt.get_state (stmt, &sval);
if (old_state == m_tainted)
{
if (ranges_have_lb && ranges_have_ub)
- sm_ctxt->set_next_state (stmt, &sval, m_stop);
+ sm_ctxt.set_next_state (stmt, &sval, m_stop);
else if (ranges_have_lb)
- sm_ctxt->set_next_state (stmt, &sval, m_has_lb);
+ sm_ctxt.set_next_state (stmt, &sval, m_has_lb);
else if (ranges_have_ub)
- sm_ctxt->set_next_state (stmt, &sval, m_has_ub);
+ sm_ctxt.set_next_state (stmt, &sval, m_has_ub);
}
else if (old_state == m_has_ub && ranges_have_lb)
- sm_ctxt->set_next_state (stmt, &sval, m_stop);
+ sm_ctxt.set_next_state (stmt, &sval, m_stop);
else if (old_state == m_has_lb && ranges_have_ub)
- sm_ctxt->set_next_state (stmt, &sval, m_stop);
+ sm_ctxt.set_next_state (stmt, &sval, m_stop);
}
bool
tainted values passed as a size to such a function. */
void
-taint_state_machine::check_for_tainted_size_arg (sm_context *sm_ctxt,
+taint_state_machine::check_for_tainted_size_arg (sm_context &sm_ctxt,
const supernode *node,
const gcall *call,
tree callee_fndecl) const
tree size_arg = gimple_call_arg (call, access->sizarg);
- state_t state = sm_ctxt->get_state (call, size_arg);
+ state_t state = sm_ctxt.get_state (call, size_arg);
enum bounds b;
if (get_taint (state, TREE_TYPE (size_arg), &b))
{
const char* const access_str =
TREE_STRING_POINTER (access->to_external_string ());
- tree diag_size = sm_ctxt->get_diagnostic_tree (size_arg);
- sm_ctxt->warn (node, call, size_arg,
- make_unique<tainted_access_attrib_size>
- (*this, diag_size, b,
- callee_fndecl,
- access->sizarg,
- access_str));
+ tree diag_size = sm_ctxt.get_diagnostic_tree (size_arg);
+ sm_ctxt.warn (node, call, size_arg,
+ make_unique<tainted_access_attrib_size>
+ (*this, diag_size, b,
+ callee_fndecl,
+ access->sizarg,
+ access_str));
}
}
}
that could be zero. */
void
-taint_state_machine::check_for_tainted_divisor (sm_context *sm_ctxt,
+taint_state_machine::check_for_tainted_divisor (sm_context &sm_ctxt,
const supernode *node,
const gassign *assign) const
{
- const region_model *old_model = sm_ctxt->get_old_region_model ();
+ const region_model *old_model = sm_ctxt.get_old_region_model ();
if (!old_model)
return;
const svalue *divisor_sval = old_model->get_rvalue (divisor_expr, NULL);
- state_t state = sm_ctxt->get_state (assign, divisor_sval);
+ state_t state = sm_ctxt.get_state (assign, divisor_sval);
enum bounds b;
if (get_taint (state, TREE_TYPE (divisor_expr), &b))
{
/* The divisor is known to not equal 0: don't warn. */
return;
- tree diag_divisor = sm_ctxt->get_diagnostic_tree (divisor_expr);
- sm_ctxt->warn (node, assign, divisor_expr,
- make_unique <tainted_divisor> (*this, diag_divisor, b));
- sm_ctxt->set_next_state (assign, divisor_sval, m_stop);
+ tree diag_divisor = sm_ctxt.get_diagnostic_tree (divisor_expr);
+ sm_ctxt.warn (node, assign, divisor_expr,
+ make_unique <tainted_divisor> (*this, diag_divisor, b));
+ sm_ctxt.set_next_state (assign, divisor_sval, m_stop);
}
}
state_t get_state_by_name (const char *name) const;
/* Return true if STMT is a function call recognized by this sm. */
- virtual bool on_stmt (sm_context *sm_ctxt,
+ virtual bool on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const = 0;
- virtual void on_phi (sm_context *sm_ctxt ATTRIBUTE_UNUSED,
+ virtual void on_phi (sm_context &sm_ctxt ATTRIBUTE_UNUSED,
const supernode *node ATTRIBUTE_UNUSED,
const gphi *phi ATTRIBUTE_UNUSED,
tree rhs ATTRIBUTE_UNUSED) const
{
}
- virtual void on_condition (sm_context *sm_ctxt ATTRIBUTE_UNUSED,
+ virtual void on_condition (sm_context &sm_ctxt ATTRIBUTE_UNUSED,
const supernode *node ATTRIBUTE_UNUSED,
const gimple *stmt ATTRIBUTE_UNUSED,
const svalue *lhs ATTRIBUTE_UNUSED,
}
virtual void
- on_bounded_ranges (sm_context *sm_ctxt ATTRIBUTE_UNUSED,
+ on_bounded_ranges (sm_context &sm_ctxt ATTRIBUTE_UNUSED,
const supernode *node ATTRIBUTE_UNUSED,
const gimple *stmt ATTRIBUTE_UNUSED,
const svalue &sval ATTRIBUTE_UNUSED,
bool inherited_state_p () const final override { return false; }
- bool on_stmt (sm_context *sm_ctxt,
+ bool on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const final override;
state_t m_ended;
private:
- void on_va_start (sm_context *sm_ctxt, const supernode *node,
+ void on_va_start (sm_context &sm_ctxt, const supernode *node,
const gcall *call) const;
- void on_va_copy (sm_context *sm_ctxt, const supernode *node,
+ void on_va_copy (sm_context &sm_ctxt, const supernode *node,
const gcall *call) const;
- void on_va_arg (sm_context *sm_ctxt, const supernode *node,
+ void on_va_arg (sm_context &sm_ctxt, const supernode *node,
const gcall *call) const;
- void on_va_end (sm_context *sm_ctxt, const supernode *node,
+ void on_va_end (sm_context &sm_ctxt, const supernode *node,
const gcall *call) const;
- void check_for_ended_va_list (sm_context *sm_ctxt,
+ void check_for_ended_va_list (sm_context &sm_ctxt,
const supernode *node,
const gcall *call,
const svalue *arg,
va_list_state_machine. */
bool
-va_list_state_machine::on_stmt (sm_context *sm_ctxt,
+va_list_state_machine::on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const
{
return false;
}
- if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
+ if (tree callee_fndecl = sm_ctxt.get_fndecl_for_call (call))
if (fndecl_built_in_p (callee_fndecl, BUILT_IN_NORMAL)
&& gimple_builtin_call_types_compatible_p (call, callee_fndecl))
switch (DECL_UNCHECKED_FUNCTION_CODE (callee_fndecl))
IDX to CALL. */
static const svalue *
-get_stateful_arg (sm_context *sm_ctxt, const gcall *call, unsigned arg_idx)
+get_stateful_arg (sm_context &sm_ctxt, const gcall *call, unsigned arg_idx)
{
tree ap = gimple_call_arg (call, arg_idx);
if (ap
&& POINTER_TYPE_P (TREE_TYPE (ap)))
{
- if (const program_state *new_state = sm_ctxt->get_new_program_state ())
+ if (const program_state *new_state = sm_ctxt.get_new_program_state ())
{
const region_model *new_model = new_state->m_region_model;
const svalue *ptr_sval = new_model->get_rvalue (ap, NULL);
/* Update state machine for a "va_start" call. */
void
-va_list_state_machine::on_va_start (sm_context *sm_ctxt,
+va_list_state_machine::on_va_start (sm_context &sm_ctxt,
const supernode *,
const gcall *call) const
{
if (arg)
{
/* Transition from start state to "started". */
- if (sm_ctxt->get_state (call, arg) == m_start)
- sm_ctxt->set_next_state (call, arg, m_started);
+ if (sm_ctxt.get_state (call, arg) == m_start)
+ sm_ctxt.set_next_state (call, arg, m_started);
}
}
/* Complain if ARG is in the "ended" state. */
void
-va_list_state_machine::check_for_ended_va_list (sm_context *sm_ctxt,
+va_list_state_machine::check_for_ended_va_list (sm_context &sm_ctxt,
const supernode *node,
const gcall *call,
const svalue *arg,
const char *usage_fnname) const
{
- if (sm_ctxt->get_state (call, arg) == m_ended)
- sm_ctxt->warn (node, call, arg,
- make_unique<va_list_use_after_va_end>
- (*this, arg, NULL_TREE, usage_fnname));
+ if (sm_ctxt.get_state (call, arg) == m_ended)
+ sm_ctxt.warn (node, call, arg,
+ make_unique<va_list_use_after_va_end>
+ (*this, arg, NULL_TREE, usage_fnname));
}
/* Get the svalue with associated va_list_state_machine state for
or NULL otherwise. */
static const svalue *
-get_stateful_va_copy_arg (sm_context *sm_ctxt,
+get_stateful_va_copy_arg (sm_context &sm_ctxt,
const gcall *call,
unsigned arg_idx)
{
- if (const program_state *new_state = sm_ctxt->get_new_program_state ())
+ if (const program_state *new_state = sm_ctxt.get_new_program_state ())
{
const region_model *new_model = new_state->m_region_model;
const svalue *arg = get_va_copy_arg (new_model, NULL, call, arg_idx);
/* Update state machine for a "va_copy" call. */
void
-va_list_state_machine::on_va_copy (sm_context *sm_ctxt,
+va_list_state_machine::on_va_copy (sm_context &sm_ctxt,
const supernode *node,
const gcall *call) const
{
if (dst_arg)
{
/* Transition from start state to "started". */
- if (sm_ctxt->get_state (call, dst_arg) == m_start)
- sm_ctxt->set_next_state (call, dst_arg, m_started);
+ if (sm_ctxt.get_state (call, dst_arg) == m_start)
+ sm_ctxt.set_next_state (call, dst_arg, m_started);
}
}
/* Update state machine for a "va_arg" call. */
void
-va_list_state_machine::on_va_arg (sm_context *sm_ctxt,
+va_list_state_machine::on_va_arg (sm_context &sm_ctxt,
const supernode *node,
const gcall *call) const
{
/* Update state machine for a "va_end" call. */
void
-va_list_state_machine::on_va_end (sm_context *sm_ctxt,
+va_list_state_machine::on_va_end (sm_context &sm_ctxt,
const supernode *node,
const gcall *call) const
{
const svalue *arg = get_stateful_arg (sm_ctxt, call, 0);
if (arg)
{
- state_t s = sm_ctxt->get_state (call, arg);
+ state_t s = sm_ctxt.get_state (call, arg);
/* Transition from "started" to "ended". */
if (s == m_started)
- sm_ctxt->set_next_state (call, arg, m_ended);
+ sm_ctxt.set_next_state (call, arg, m_ended);
else if (s == m_ended)
check_for_ended_va_list (sm_ctxt, node, call, arg, "va_end");
}
bool inherited_state_p () const final override { return false; }
- bool on_stmt (sm_context *sm_ctxt,
+ bool on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const final override;
bool can_purge_p (state_t s) const final override;
- void check_for_pyobject_usage_without_gil (sm_context *sm_ctxt,
+ void check_for_pyobject_usage_without_gil (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
tree op) const;
private:
- void check_for_pyobject_in_call (sm_context *sm_ctxt,
+ void check_for_pyobject_in_call (sm_context &sm_ctxt,
const supernode *node,
const gcall *call,
tree callee_fndecl) const;
struct cb_data
{
- cb_data (const gil_state_machine &sm, sm_context *sm_ctxt,
+ cb_data (const gil_state_machine &sm, sm_context &sm_ctxt,
const supernode *snode, const gimple *stmt)
: m_sm (sm), m_sm_ctxt (sm_ctxt), m_snode (snode), m_stmt (stmt)
{
}
const gil_state_machine &m_sm;
- sm_context *m_sm_ctxt;
+ sm_context &m_sm_ctxt;
const supernode *m_snode;
const gimple *m_stmt;
};
PyObject * arguments passed to CALL. */
void
-gil_state_machine::check_for_pyobject_in_call (sm_context *sm_ctxt,
+gil_state_machine::check_for_pyobject_in_call (sm_context &sm_ctxt,
const supernode *node,
const gcall *call,
tree callee_fndecl) const
tree type = TREE_TYPE (TREE_TYPE (arg));
if (type_based_on_pyobject_p (type))
{
- sm_ctxt->warn (node, call, NULL_TREE,
- make_unique<fncall_without_gil> (*this, call,
- callee_fndecl,
- i));
- sm_ctxt->set_global_state (m_stop);
+ sm_ctxt.warn (node, call, NULL_TREE,
+ make_unique<fncall_without_gil> (*this, call,
+ callee_fndecl,
+ i));
+ sm_ctxt.set_global_state (m_stop);
}
}
}
/* Implementation of state_machine::on_stmt vfunc for gil_state_machine. */
bool
-gil_state_machine::on_stmt (sm_context *sm_ctxt,
+gil_state_machine::on_stmt (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt) const
{
- const state_t global_state = sm_ctxt->get_global_state ();
+ const state_t global_state = sm_ctxt.get_global_state ();
if (const gcall *call = dyn_cast <const gcall *> (stmt))
{
- if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
+ if (tree callee_fndecl = sm_ctxt.get_fndecl_for_call (call))
{
if (is_named_call_p (callee_fndecl, "PyEval_SaveThread", call, 0))
{
"PyEval_SaveThread");
if (global_state == m_released_gil)
{
- sm_ctxt->warn (node, stmt, NULL_TREE,
- make_unique<double_save_thread> (*this, call));
- sm_ctxt->set_global_state (m_stop);
+ sm_ctxt.warn (node, stmt, NULL_TREE,
+ make_unique<double_save_thread> (*this, call));
+ sm_ctxt.set_global_state (m_stop);
}
else
- sm_ctxt->set_global_state (m_released_gil);
+ sm_ctxt.set_global_state (m_released_gil);
return true;
}
else if (is_named_call_p (callee_fndecl, "PyEval_RestoreThread",
inform (input_location, "found call to %qs",
"PyEval_SaveThread");
if (global_state == m_released_gil)
- sm_ctxt->set_global_state (m_start);
+ sm_ctxt.set_global_state (m_start);
return true;
}
else if (global_state == m_released_gil)
}
void
-gil_state_machine::check_for_pyobject_usage_without_gil (sm_context *sm_ctxt,
+gil_state_machine::check_for_pyobject_usage_without_gil (sm_context &sm_ctxt,
const supernode *node,
const gimple *stmt,
tree op) const
tree type = TREE_TYPE (op);
if (type_based_on_pyobject_p (type))
{
- sm_ctxt->warn (node, stmt, NULL_TREE,
- make_unique<pyobject_usage_without_gil> (*this, op));
- sm_ctxt->set_global_state (m_stop);
+ sm_ctxt.warn (node, stmt, NULL_TREE,
+ make_unique<pyobject_usage_without_gil> (*this, op));
+ sm_ctxt.set_global_state (m_stop);
}
}