diff options
author | Martin Jambor <mjambor@suse.cz> | 2014-06-20 13:19:46 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2014-06-20 13:19:46 +0200 |
commit | bec81025ed968d6ba52308b2a9824bd689628a5f (patch) | |
tree | 2e698ba10b69273f2d61373633942ad57673a8b7 /gcc | |
parent | bf613c022efe5ef454c39d20d555c552995ec899 (diff) | |
download | gcc-bec81025ed968d6ba52308b2a9824bd689628a5f.zip gcc-bec81025ed968d6ba52308b2a9824bd689628a5f.tar.gz gcc-bec81025ed968d6ba52308b2a9824bd689628a5f.tar.bz2 |
re PR ipa/61540 (internal compiler error in try_make_edge_direct_virtual_call)
2014-06-20 Martin Jambor <mjambor@suse.cz>
PR ipa/61540
* ipa-prop.c (impossible_devirt_target): New function.
(try_make_edge_direct_virtual_call): Use it, also instead of
asserting.
testsuite/
* g++.dg/ipa/pr61540.C: New test.
From-SVN: r211847
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/pr61540.C | 41 |
4 files changed, 80 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f26115d..fde7c41 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2014-06-20 Martin Jambor <mjambor@suse.cz> + + PR ipa/61540 + * ipa-prop.c (impossible_devirt_target): New function. + (try_make_edge_direct_virtual_call): Use it, also instead of + asserting. + 2014-06-20 Yury Gribov <y.gribov@samsung.com> Max Ostapenko <m.ostapenko@partner.samsung.com> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index b67deed..d9dca52 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -2912,6 +2912,29 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie, return cs; } +/* Return the target to be used in cases of impossible devirtualization. IE + and target (the latter can be NULL) are dumped when dumping is enabled. */ + +static tree +impossible_devirt_target (struct cgraph_edge *ie, tree target) +{ + if (dump_file) + { + if (target) + fprintf (dump_file, + "Type inconsident devirtualization: %s/%i->%s\n", + ie->caller->name (), ie->caller->order, + IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target))); + else + fprintf (dump_file, + "No devirtualization target in %s/%i\n", + ie->caller->name (), ie->caller->order); + } + tree new_target = builtin_decl_implicit (BUILT_IN_UNREACHABLE); + cgraph_get_create_node (new_target); + return new_target; +} + /* Try to find a destination for indirect edge IE that corresponds to a virtual call based on a formal parameter which is described by jump function JFUNC and if it can be determined, make it direct and return the direct edge. @@ -2946,15 +2969,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie, && DECL_FUNCTION_CODE (target) == BUILT_IN_UNREACHABLE) || !possible_polymorphic_call_target_p (ie, cgraph_get_node (target))) - { - if (dump_file) - fprintf (dump_file, - "Type inconsident devirtualization: %s/%i->%s\n", - ie->caller->name (), ie->caller->order, - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target))); - target = builtin_decl_implicit (BUILT_IN_UNREACHABLE); - cgraph_get_create_node (target); - } + target = impossible_devirt_target (ie, target); return ipa_make_edge_direct_to_target (ie, target); } } @@ -2984,10 +2999,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie, if (targets.length () == 1) target = targets[0]->decl; else - { - target = builtin_decl_implicit (BUILT_IN_UNREACHABLE); - cgraph_get_create_node (target); - } + target = impossible_devirt_target (ie, NULL_TREE); } else { @@ -3002,10 +3014,8 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie, if (target) { -#ifdef ENABLE_CHECKING - gcc_assert (possible_polymorphic_call_target_p - (ie, cgraph_get_node (target))); -#endif + if (!possible_polymorphic_call_target_p (ie, cgraph_get_node (target))) + target = impossible_devirt_target (ie, target); return ipa_make_edge_direct_to_target (ie, target); } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ffb5caf..0cceea5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-06-20 Martin Jambor <mjambor@suse.cz> + + PR ipa/61540 + * g++.dg/ipa/pr61540.C: New test. + 2014-06-20 Yury Gribov <y.gribov@samsung.com> Max Ostapenko <m.ostapenko@partner.samsung.com> diff --git a/gcc/testsuite/g++.dg/ipa/pr61540.C b/gcc/testsuite/g++.dg/ipa/pr61540.C new file mode 100644 index 0000000..d298964 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr61540.C @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-early-inlining -fdump-ipa-cp" } */ + +struct data { + data(int) {} +}; + +struct top { + virtual int topf() {} +}; + +struct intermediate: top { + int topf() /* override */ { return 0; } +}; + +struct child1: top { + void childf() + { + data d(topf()); + } +}; + +struct child2: intermediate {}; + +void test(top& t) +{ + child1& c = static_cast<child1&>(t); + c.childf(); + child2 d; + test(d); +} + +int main (int argc, char **argv) +{ + child1 c; + test (c); + return 0; +} + +/* { dg-final { scan-ipa-dump "Type inconsident devirtualization" "cp" } } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */ |