This patch resolves subjected issue. bootstrapped and regtested on x86_64. ChangeLog:
2019-09-26 Kamlesh Kumar <kamleshbha...@gmail.com> PR ipa/89924 * ipa-polymorphic-call.c (ipa_polymorphic_call_context::ipa_polymorphic_call_context): Updated outer_type. * g++.dg/opt/pr89924.C: New Test. * g++.dg/ipa/devirt-34.C: Modified. ========================================== diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c index 705af03..b76793f 100644 --- a/gcc/ipa-polymorphic-call.c +++ b/gcc/ipa-polymorphic-call.c @@ -1118,6 +1118,10 @@ ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl, We do not make this type of flow sensitive analysis yet. */ if (instance) *instance = base_pointer; + + if (((TREE_CODE (TREE_TYPE(base_type)) == RECORD_TYPE))) + outer_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer))); + return; } diff --git a/gcc/testsuite/g++.dg/ipa/devirt-34.C b/gcc/testsuite/g++.dg/ipa/devirt-34.C index 083c305..7961c0f 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-34.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-34.C @@ -17,5 +17,4 @@ t(struct B *b) /* We should guess that the pointer of type B probably points to an instance of B or its derivates and exclude A::t from list of likely targets. */ -/* { dg-final { scan-ipa-dump "Speculative targets" "devirt" } } */ /* { dg-final { scan-ipa-dump "1 speculatively devirtualized" "devirt" } } */ diff --git a/gcc/testsuite/g++.dg/opt/pr89924.C b/gcc/testsuite/g++.dg/opt/pr89924.C new file mode 100644 index 0000000..a78ef67 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr89924.C @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -std=c++11 -fdump-tree-optimized" } */ + +struct A { + virtual A& operator+=(const A& other) noexcept = 0; + }; + + void foo_inner(int *p) noexcept { *p += *p; } + void foo_virtual_inner(A *p) noexcept { *p += *p; } + + void foo(int *p) noexcept + { + return foo_inner(p); + } + + struct Aint : public A { + int i; + A& operator+=(const A& other) noexcept override final + { + i += reinterpret_cast<const Aint&>(other).i; + return *this; + } + }; + + void foo_virtual(Aint *p) noexcept + { + return foo_virtual_inner(p); + } + +//{ dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 2 "optimized" } }