From fefc209299236593fcc3004c874b2602a3735056 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 22 Sep 2020 11:29:02 -0400 Subject: [PATCH] analyzer: use switch in exploded_node::on_stmt This patch replaces a sequence of dyn_cast to different gimple stmt types in exploded_node::on_stmt with a switch on the gimple_code. This makes clearer which kinds of stmt are currently treated as no-ops, as a precursor to handling them properly. No functional change intended. gcc/analyzer/ChangeLog: * engine.cc (exploded_node::on_stmt): Replace sequence of dyn_cast with switch. --- gcc/analyzer/engine.cc | 134 ++++++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 54 deletions(-) diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index df7e33564f1..437429798f2 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -1063,62 +1063,88 @@ exploded_node::on_stmt (exploded_graph &eg, &old_state, state, stmt); - if (const gassign *assign = dyn_cast (stmt)) - state->m_region_model->on_assignment (assign, &ctxt); - - if (const greturn *return_ = dyn_cast (stmt)) - state->m_region_model->on_return (return_, &ctxt); - - /* Track whether we have a gcall to a function that's not recognized by - anything, for which we don't have a function body, or for which we - don't know the fndecl. */ bool unknown_side_effects = false; - if (const gcall *call = dyn_cast (stmt)) + + switch (gimple_code (stmt)) { - /* Debugging/test support. */ - if (is_special_named_call_p (call, "__analyzer_describe", 2)) - state->m_region_model->impl_call_analyzer_describe (call, &ctxt); - else if (is_special_named_call_p (call, "__analyzer_dump", 0)) - { - /* Handle the builtin "__analyzer_dump" by dumping state - to stderr. */ - state->dump (eg.get_ext_state (), true); - } - else if (is_special_named_call_p (call, "__analyzer_dump_path", 0)) - { - /* Handle the builtin "__analyzer_dump_path" by queuing a - diagnostic at this exploded_node. */ - ctxt.warn (new dump_path_diagnostic ()); - } - else if (is_special_named_call_p (call, "__analyzer_dump_region_model", 0)) - { - /* Handle the builtin "__analyzer_dump_region_model" by dumping - the region model's state to stderr. */ - state->m_region_model->dump (false); - } - else if (is_special_named_call_p (call, "__analyzer_eval", 1)) - state->m_region_model->impl_call_analyzer_eval (call, &ctxt); - else if (is_special_named_call_p (call, "__analyzer_break", 0)) - { - /* Handle the builtin "__analyzer_break" by triggering a - breakpoint. */ - /* TODO: is there a good cross-platform way to do this? */ - raise (SIGINT); - } - else if (is_special_named_call_p (call, "__analyzer_dump_exploded_nodes", - 1)) - { - /* This is handled elsewhere. */ - } - else if (is_setjmp_call_p (call)) - state->m_region_model->on_setjmp (call, this, &ctxt); - else if (is_longjmp_call_p (call)) - { - on_longjmp (eg, call, state, &ctxt); - return on_stmt_flags::terminate_path (); - } - else - unknown_side_effects = state->m_region_model->on_call_pre (call, &ctxt); + default: + /* No-op for now. */ + break; + + case GIMPLE_ASSIGN: + { + const gassign *assign = as_a (stmt); + state->m_region_model->on_assignment (assign, &ctxt); + } + break; + + case GIMPLE_ASM: + /* No-op for now. */ + break; + + case GIMPLE_CALL: + { + /* Track whether we have a gcall to a function that's not recognized by + anything, for which we don't have a function body, or for which we + don't know the fndecl. */ + const gcall *call = as_a (stmt); + + /* Debugging/test support. */ + if (is_special_named_call_p (call, "__analyzer_describe", 2)) + state->m_region_model->impl_call_analyzer_describe (call, &ctxt); + else if (is_special_named_call_p (call, "__analyzer_dump", 0)) + { + /* Handle the builtin "__analyzer_dump" by dumping state + to stderr. */ + state->dump (eg.get_ext_state (), true); + } + else if (is_special_named_call_p (call, "__analyzer_dump_path", 0)) + { + /* Handle the builtin "__analyzer_dump_path" by queuing a + diagnostic at this exploded_node. */ + ctxt.warn (new dump_path_diagnostic ()); + } + else if (is_special_named_call_p (call, "__analyzer_dump_region_model", + 0)) + { + /* Handle the builtin "__analyzer_dump_region_model" by dumping + the region model's state to stderr. */ + state->m_region_model->dump (false); + } + else if (is_special_named_call_p (call, "__analyzer_eval", 1)) + state->m_region_model->impl_call_analyzer_eval (call, &ctxt); + else if (is_special_named_call_p (call, "__analyzer_break", 0)) + { + /* Handle the builtin "__analyzer_break" by triggering a + breakpoint. */ + /* TODO: is there a good cross-platform way to do this? */ + raise (SIGINT); + } + else if (is_special_named_call_p (call, + "__analyzer_dump_exploded_nodes", + 1)) + { + /* This is handled elsewhere. */ + } + else if (is_setjmp_call_p (call)) + state->m_region_model->on_setjmp (call, this, &ctxt); + else if (is_longjmp_call_p (call)) + { + on_longjmp (eg, call, state, &ctxt); + return on_stmt_flags::terminate_path (); + } + else + unknown_side_effects + = state->m_region_model->on_call_pre (call, &ctxt); + } + break; + + case GIMPLE_RETURN: + { + const greturn *return_ = as_a (stmt); + state->m_region_model->on_return (return_, &ctxt); + } + break; } bool any_sm_changes = false; -- 2.30.2