public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Ankur saini <arsenic@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/arsenic/heads/polymorphic_call)] analyzer: detect and analyzer vfunc calls Date: Sun, 1 Aug 2021 09:21:49 +0000 (GMT) [thread overview] Message-ID: <20210801092149.E94BF383B42C@sourceware.org> (raw) https://gcc.gnu.org/g:450989a9458e3d0087b01a2bb04b7667fb60afb5 commit 450989a9458e3d0087b01a2bb04b7667fb60afb5 Author: Ankur Saini <arsenic@sourceware.org> Date: Thu Jul 29 17:20:10 2021 +0530 analyzer: detect and analyzer vfunc calls Diff: --- gcc/analyzer/engine.cc | 61 ++++++++++++++++++++++++++++++++++++++----- gcc/analyzer/program-state.cc | 5 ++-- gcc/analyzer/program-state.h | 3 ++- gcc/analyzer/region-model.cc | 11 +++++--- gcc/analyzer/region-model.h | 3 ++- 5 files changed, 69 insertions(+), 14 deletions(-) diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index 29209030b5b..f4cf0864008 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -65,6 +65,7 @@ along with GCC; see the file COPYING3. If not see #include <zlib.h> #include "plugin.h" #include "target.h" +#include "ipa-utils.h" /* For an overview, see gcc/doc/analyzer.texi. */ @@ -1242,6 +1243,17 @@ exploded_node::on_stmt (exploded_graph &eg, unknown_side_effects = false; } + /* If the statmement is a polymorphic call then assume + there are no side effects. */ + gimple *call_stmt = const_cast<gimple *>(stmt); + if (gcall *call = dyn_cast<gcall *> (call_stmt)) + { + function *fun = this->get_function(); + cgraph_edge *e = cgraph_node::get (fun->decl)->get_edge (call); + if ((e && e->indirect_info) && (e->indirect_info->polymorphic)) + unknown_side_effects = false; + } + on_stmt_post (stmt, state, unknown_side_effects, &ctxt); return on_stmt_flags (); @@ -3035,12 +3047,11 @@ void exploded_graph::create_dynamic_call (const gcall *call, tree fn_decl, exploded_node *node, - program_state &next_state, + program_state next_state, program_point &next_point, uncertainty_t *uncertainty) { const program_point *this_point = &node->get_point (); - // assert for fn_decl ? function *fun = DECL_STRUCT_FUNCTION (fn_decl); if (fun) { @@ -3055,7 +3066,7 @@ exploded_graph::create_dynamic_call (const gcall *call, new_point.push_to_call_stack (sn_exit, next_point.get_supernode()); - next_state.push_call (*this, node, call, uncertainty); + next_state.push_call (*this, node, call, uncertainty, fn_decl); // TODO: add some logging here regarding dynamic call @@ -3327,9 +3338,47 @@ exploded_graph::process_node (exploded_node *node) region_model *model = state.m_region_model; /* Call is possibly happening via a function pointer. */ - if (tree fn_decl = model->get_fndecl_for_call(call,&ctxt)) - create_dynamic_call (call, fn_decl, node, next_state, - next_point, &uncertainty); + if (tree fn_decl = model->get_fndecl_for_call (call,&ctxt)) + create_dynamic_call (call, + fn_decl, + node, + next_state, + next_point, + &uncertainty); + else + { + /* Call is possibly a polymorphic call. + + In such case, use devirtisation tools to find + possible callees of this function call and let the + analyzer specluate them all. */ + function *fun = node->get_function (); + gcall *stmt = const_cast<gcall *>(call); + cgraph_edge *e + = cgraph_node::get (fun->decl)->get_edge (stmt); + if (e->indirect_info->polymorphic) + { + void *cache_token; + bool final; + vec <cgraph_node *> targets + = possible_polymorphic_call_targets (e, + &final, + &cache_token, + true); + for (cgraph_node *x : targets) + { + if (logger) + logger->log ("found call to : %s\n", + x->dump_name()); + create_dynamic_call (stmt, + x->decl, + node, + next_state, + next_point, + &uncertainty); + } + } + } } if (!node->on_edge (*this, succ, &next_point, &next_state, diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc index eb05994f0ef..b1c1d67bb8b 100644 --- a/gcc/analyzer/program-state.cc +++ b/gcc/analyzer/program-state.cc @@ -1042,7 +1042,8 @@ void program_state::push_call (exploded_graph &eg, exploded_node *enode, const gcall *call_stmt, - uncertainty_t *uncertainty) + uncertainty_t *uncertainty, + tree fn_decl) { /* Update state. */ const program_point &point = enode->get_point (); @@ -1053,7 +1054,7 @@ program_state::push_call (exploded_graph &eg, this, uncertainty, last_stmt); - m_region_model->update_for_gcall (call_stmt, &ctxt); + m_region_model->update_for_gcall(call_stmt, &ctxt, fn_decl); } /* Update this program_state to reflect a return from function diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h index 658dbb69075..f4bd4cbcf49 100644 --- a/gcc/analyzer/program-state.h +++ b/gcc/analyzer/program-state.h @@ -221,7 +221,8 @@ public: void push_call (exploded_graph &eg, exploded_node *enode, const gcall *call_stmt, - uncertainty_t *uncertainty); + uncertainty_t *uncertainty, + tree fn_decl = NULL); void returning_call (exploded_graph &eg, exploded_node *enode, diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 1e86d1f3bf8..935a8c6431a 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -3140,7 +3140,8 @@ region_model::maybe_update_for_edge (const superedge &edge, void region_model::update_for_gcall (const gcall *call_stmt, - region_model_context *ctxt) + region_model_context *ctxt, + tree fn_decl) { /* Build a vec of argument svalues, using the current top frame for resolving tree expressions. */ @@ -3151,9 +3152,11 @@ region_model::update_for_gcall (const gcall *call_stmt, tree arg = gimple_call_arg (call_stmt, i); arg_svals.quick_push (get_rvalue (arg, ctxt)); } - - /* Get the function * from the call. */ - tree fn_decl = get_fndecl_for_call (call_stmt,ctxt); + + /* Get the fn_decl from the call if not provided as argument. */ + if (!fn_decl) + fn_decl = get_fndecl_for_call (call_stmt,ctxt); + function *fun = DECL_STRUCT_FUNCTION (fn_decl); push_frame (fun, &arg_svals, ctxt); } diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index a15bc9e2f6d..f06788771dc 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -590,7 +590,8 @@ class region_model rejected_constraint **out); void update_for_gcall (const gcall *call_stmt, - region_model_context *ctxt); + region_model_context *ctxt, + tree fn_decl = NULL); void update_for_return_gcall (const gcall *call_stmt, region_model_context *ctxt);
reply other threads:[~2021-08-01 9:21 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210801092149.E94BF383B42C@sourceware.org \ --to=arsenic@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).