diff options
author | Martin Jambor <mjambor@suse.cz> | 2013-06-25 13:09:21 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2013-06-25 13:09:21 +0200 |
commit | c13bc3d998b26a9d50c6bb07d0f8f372117e7a20 (patch) | |
tree | d82bab7c445398d72a006a056d61c12cf0f00522 | |
parent | 6cdbb7e8a1f92fcc2504d56d68ff981803d499a7 (diff) | |
download | gcc-c13bc3d998b26a9d50c6bb07d0f8f372117e7a20.zip gcc-c13bc3d998b26a9d50c6bb07d0f8f372117e7a20.tar.gz gcc-c13bc3d998b26a9d50c6bb07d0f8f372117e7a20.tar.bz2 |
re PR middle-end/57670 (Member-pointer calls should not be redirected to builtin_unreachable)
2013-06-25 Martin Jambor <mjambor@suse.cz>
PR middle-end/57670
* cgraph.h (cgraph_indirect_call_info): New flag member_ptr.
* ipa-prop.c (ipa_print_node_jump_functions): Mark member pointer
calls in the dump.
(ipa_note_param_call): Initialize member_ptr flag.
(ipa_analyze_indirect_call_uses): Set member_ptr flag.
(ipa_make_edge_direct_to_target): Bail out if member_ptr is set.
(ipa_write_indirect_edge_info): Stream member_ptr flag.
(ipa_read_indirect_edge_info): Likewise.
testsuite/
* g++.dg/ipa/pr57670.C (H): New test.
From-SVN: r200393
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cgraph.h | 2 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/pr57670.C | 37 |
5 files changed, 66 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f0af61e..9367386 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2013-06-25 Martin Jambor <mjambor@suse.cz> + + PR middle-end/57670 + * cgraph.h (cgraph_indirect_call_info): New flag member_ptr. + * ipa-prop.c (ipa_print_node_jump_functions): Mark member pointer + calls in the dump. + (ipa_note_param_call): Initialize member_ptr flag. + (ipa_analyze_indirect_call_uses): Set member_ptr flag. + (ipa_make_edge_direct_to_target): Bail out if member_ptr is set. + (ipa_write_indirect_edge_info): Stream member_ptr flag. + (ipa_read_indirect_edge_info): Likewise. + 2013-06-25 Richard Biener <rguenther@suse.de> PR middle-end/56977 diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 1e17cb7..e66eecd 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -440,6 +440,8 @@ struct GTY(()) cgraph_indirect_call_info /* Set when the call is a call of a pointer loaded from contents of an aggregate at offset. */ unsigned agg_contents : 1; + /* Set when this is a call through a member pointer. */ + unsigned member_ptr : 1; /* When the previous bit is set, this one determines whether the destination is loaded from a parameter passed by reference. */ unsigned by_ref : 1; diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index ae6825b..62d7a3c 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -303,8 +303,9 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node) ii = cs->indirect_info; if (ii->agg_contents) - fprintf (f, " indirect aggregate callsite, calling param %i, " + fprintf (f, " indirect %s callsite, calling param %i, " "offset " HOST_WIDE_INT_PRINT_DEC ", %s", + ii->member_ptr ? "member ptr" : "aggregate", ii->param_index, ii->offset, ii->by_ref ? "by reference" : "by_value"); else @@ -1626,6 +1627,7 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt) cs->indirect_info->offset = 0; cs->indirect_info->polymorphic = 0; cs->indirect_info->agg_contents = 0; + cs->indirect_info->member_ptr = 0; return cs; } @@ -1819,6 +1821,7 @@ ipa_analyze_indirect_call_uses (struct cgraph_node *node, struct cgraph_edge *cs = ipa_note_param_call (node, index, call); cs->indirect_info->offset = offset; cs->indirect_info->agg_contents = 1; + cs->indirect_info->member_ptr = 1; } return; @@ -2239,6 +2242,10 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target) target = canonicalize_constructor_val (target, NULL); if (!target || TREE_CODE (target) != FUNCTION_DECL) { + if (ie->indirect_info->member_ptr) + /* Member pointer call that goes through a VMT lookup. */ + return NULL; + if (dump_file) fprintf (dump_file, "ipa-prop: Discovered direct call to non-function" " in %s/%i, making it unreachable.\n", @@ -3792,6 +3799,7 @@ ipa_write_indirect_edge_info (struct output_block *ob, bp = bitpack_create (ob->main_stream); bp_pack_value (&bp, ii->polymorphic, 1); bp_pack_value (&bp, ii->agg_contents, 1); + bp_pack_value (&bp, ii->member_ptr, 1); bp_pack_value (&bp, ii->by_ref, 1); streamer_write_bitpack (&bp); @@ -3818,6 +3826,7 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib, bp = streamer_read_bitpack (ib); ii->polymorphic = bp_unpack_value (&bp, 1); ii->agg_contents = bp_unpack_value (&bp, 1); + ii->member_ptr = bp_unpack_value (&bp, 1); ii->by_ref = bp_unpack_value (&bp, 1); if (ii->polymorphic) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8c9f01a..380fbf5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-06-25 Martin Jambor <mjambor@suse.cz> + + PR middle-end/57670 + * g++.dg/ipa/pr57670.C: New test. + 2013-06-25 Richard Biener <rguenther@suse.de> PR middle-end/56977 diff --git a/gcc/testsuite/g++.dg/ipa/pr57670.C b/gcc/testsuite/g++.dg/ipa/pr57670.C new file mode 100644 index 0000000..400612e --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr57670.C @@ -0,0 +1,37 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining" } */ + +class H +{ +public: + virtual unsigned bar() const { return 16; } +}; + +class A : public H +{ + unsigned foo(unsigned (H::*func)(void) const) const; +public: + H *h; + virtual unsigned bar() const; +}; + +unsigned A::foo(unsigned (H::*func)(void) const) const +{ + return (h->*func)(); +} + +unsigned A::bar() const +{ + return foo(&H::bar); +} + +int main (int argc, char **argv) +{ + H h; + A a; + a.h = &h; + + if (a.bar() != 16) + __builtin_abort (); + return 0; +} |