From b786d31f62a93acc810f7bf5271c1bc80f259a8d Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 15 Dec 2013 23:19:33 +0100 Subject: [PATCH] re PR ipa/59265 (Segmentation fault in ipa_note_param_call for -fprofile-use in SPEC CPU2006) PR ipa/59265 * ipa-prop.c (ipa_analyze_call_uses): Skip already devirtualized calls. g++.dg/torture/pr59265.C: New testcase. From-SVN: r206004 --- gcc/ChangeLog | 5 +++++ gcc/ipa-prop.c | 11 ++++++++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/torture/pr59265.C | 22 ++++++++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr59265.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 93e857df8dc..023a2291bac 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2013-12-14 Jan Hubicka + PR ipa/59265 + * ipa-prop.c (ipa_analyze_call_uses): Skip already + devirtualized calls. + +2013-12-14 Jan Hubicka PR middle-end/58477 * ipa-prop.c (stmt_may_be_vtbl_ptr_store): Skip clobbers. diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 650e6002b87..a753c040b9e 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -2024,8 +2024,17 @@ ipa_analyze_call_uses (struct cgraph_node *node, struct param_analysis_info *parms_ainfo, gimple call) { tree target = gimple_call_fn (call); + struct cgraph_edge *cs; - if (!target) + if (!target + || (TREE_CODE (target) != SSA_NAME + && !virtual_method_call_p (target))) + return; + + /* If we previously turned the call into a direct call, there is + no need to analyze. */ + cs = cgraph_edge (node, call); + if (cs && !cs->indirect_unknown_callee) return; if (TREE_CODE (target) == SSA_NAME) ipa_analyze_indirect_call_uses (node, info, parms_ainfo, call, target); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a04e6621e0c..f143da257fe 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-12-14 Jan Hubicka + + PR ipa/59265 + g++.dg/torture/pr59265.C: New testcase. + 2013-12-15 Uros Bizjak * gcc.dg/vect/vect-nop-move.c (foo32x2_be): Call diff --git a/gcc/testsuite/g++.dg/torture/pr59265.C b/gcc/testsuite/g++.dg/torture/pr59265.C new file mode 100644 index 00000000000..880c454da10 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr59265.C @@ -0,0 +1,22 @@ +// { dg-do compile } +// { dg-options "-fprofile-use -std=gnu++11" } + +class A { + int m_fn1() const; + unsigned m_fn2() const; +}; +class B { +public: + virtual void m_fn1(); +}; +class C final : B { + C(); + virtual void m_fn2() { m_fn1(); } +}; +int a; +unsigned A::m_fn2() const { + if (m_fn1()) + return 0; + a = m_fn2(); +} +C::C() {} -- 2.30.2