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" } }

Reply via email to