Commit 458a1cd0 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 37144e84
2016-08-17 Jakub Jelinek <jakub@redhat.com>
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 <cltang@codesourcery.com>
* omp-low.c (lower_oacc_reductions): Adjust variable lookup to use
......
2016-08-17 Jakub Jelinek <jakub@redhat.com>
PR middle-end/77259
* g++.dg/ipa/devirt-52.C: New test.
2016-08-17 Chung-Lin Tang <cltang@codesourcery.com>
* c-c++-common/goacc/reduction-6.c: New testcase.
......
// PR middle-end/77259
// { dg-do compile { target c++11 } }
// { dg-options "-O2" }
template <typename, typename = int> class A;
template <typename, typename> struct A
{
A (A &&);
};
template <typename S, typename T, typename U>
A<S> operator+(S *, const A<T, U> &);
template <typename S, typename T, typename U>
void operator+(const A<T, U> &, S *);
struct B
{
template <typename V> B (V);
};
template <typename V> V foo (B) {}
class C;
template <typename> struct D
{
C *operator->() { return d; }
C *d;
};
struct C
{
virtual A<int> bar ();
};
struct E
{
~E ();
virtual A<char> bar (const B &) const;
};
template <typename> struct F : E
{
};
template <typename W> struct F<D<W>> : E
{
A<char> bar (const B &) const try
{
D<W> a = baz ();
}
catch (int)
{
}
D<W> baz () const
{
D<C> b = foo<D<C>>(0);
"" + b->bar () + "";
}
};
struct G : F<D<int>>
{
G (int);
};
void test () { G (0); }
......@@ -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);
......
......@@ -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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment