From: Jakub Jelinek Date: Wed, 17 Aug 2016 13:56:30 +0000 (+0200) Subject: re PR middle-end/77259 (ICE in emit_move_insn since r232167) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=458a1cd089646f1308c6c19573d095852f10d91d;p=gcc.git re PR middle-end/77259 (ICE in emit_move_insn since r232167) PR middle-end/77259 * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): If turning a call into __builtin_unreachable-like noreturn call, adjust gimple_call_set_fntype. * tree-cfgcleanup.c (fixup_noreturn_call): Remove lhs also if gimple_call_fntype has void return type. * g++.dg/ipa/devirt-52.C: New test. From-SVN: r239537 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2f19c2585e1..9bb3824437b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-08-17 Jakub Jelinek + + PR middle-end/77259 + * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): If + turning a call into __builtin_unreachable-like noreturn call, adjust + gimple_call_set_fntype. + * tree-cfgcleanup.c (fixup_noreturn_call): Remove lhs also if + gimple_call_fntype has void return type. + 2016-08-17 Chung-Lin Tang * omp-low.c (lower_oacc_reductions): Adjust variable lookup to use diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0595ceb9d75..36238859838 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-08-17 Jakub Jelinek + + PR middle-end/77259 + * g++.dg/ipa/devirt-52.C: New test. + 2016-08-17 Chung-Lin Tang * c-c++-common/goacc/reduction-6.c: New testcase. diff --git a/gcc/testsuite/g++.dg/ipa/devirt-52.C b/gcc/testsuite/g++.dg/ipa/devirt-52.C new file mode 100644 index 00000000000..be0ab4c3621 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-52.C @@ -0,0 +1,56 @@ +// PR middle-end/77259 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +template class A; +template struct A +{ + A (A &&); +}; +template +A operator+(S *, const A &); +template +void operator+(const A &, S *); +struct B +{ + template B (V); +}; +template V foo (B) {} +class C; +template struct D +{ + C *operator->() { return d; } + C *d; +}; +struct C +{ + virtual A bar (); +}; +struct E +{ + ~E (); + virtual A bar (const B &) const; +}; +template struct F : E +{ +}; +template struct F> : E +{ + A bar (const B &) const try + { + D a = baz (); + } + catch (int) + { + } + D baz () const + { + D b = foo>(0); + "" + b->bar () + ""; + } +}; +struct G : F> +{ + G (int); +}; +void test () { G (0); } diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 3fe0d3e8994..6052872cb57 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -602,9 +602,14 @@ fixup_noreturn_call (gimple *stmt) /* If there is an LHS, remove it, but only if its type has fixed size. The LHS will need to be recreated during RTL expansion and creating temporaries of variable-sized types is not supported. Also don't - do this with TREE_ADDRESSABLE types, as assign_temp will abort. */ + do this with TREE_ADDRESSABLE types, as assign_temp will abort. + Drop LHS regardless of TREE_ADDRESSABLE, if the function call + has been changed into a call that does not return a value, like + __builtin_unreachable or __cxa_pure_virtual. */ tree lhs = gimple_call_lhs (stmt); - if (should_remove_lhs_p (lhs)) + if (lhs + && (should_remove_lhs_p (lhs) + || VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (stmt))))) { gimple_call_set_lhs (stmt, NULL_TREE); diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index edc3fdf2a79..5d21c80493a 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -4543,6 +4543,15 @@ eliminate_dom_walker::before_dom_children (basic_block b) lang_hooks.decl_printable_name (fn, 2)); } gimple_call_set_fndecl (call_stmt, fn); + /* If changing the call to __builtin_unreachable + or similar noreturn function, adjust gimple_call_fntype + too. */ + if (gimple_call_noreturn_p (call_stmt) + && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fn))) + && TYPE_ARG_TYPES (TREE_TYPE (fn)) + && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fn))) + == void_type_node)) + gimple_call_set_fntype (call_stmt, TREE_TYPE (fn)); maybe_remove_unused_call_args (cfun, call_stmt); gimple_set_modified (stmt, true); }