[PATCH, PR 61540] Do not ICE on impossible devirtualization
Jan Hubicka
hubicka@ucw.cz
Thu Jun 19 16:51:00 GMT 2014
> Hi,
>
> On Wed, Jun 18, 2014 at 06:12:34PM +0200, Bernhard Reutner-Fischer wrote:
> > On 18 June 2014 10:24:16 Martin Jambor <mjambor@suse.cz> wrote:
> >
> > >@@ -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)))
> > >+ return ipa_make_edge_direct_to_target (ie, target);
> > > return ipa_make_edge_direct_to_target (ie, target);
> > > }
> >
> > The above looks odd. You return the same thing both conditionally
> > and unconditionally?
> >
>
> You are obviously right, apparently I was too tired to attempt to work
> that night. Thanks, for spotting it. The following patch has this
> corrected and it also passes bootstrap and testing on x86_64-linux on
> both the trunk and the 4.9 branch. OK for both?
OK,
Honza
>
> Thanks,
>
> Martin
>
>
> 2014-06-19 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.
>
> 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/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" } } */
More information about the Gcc-patches
mailing list