Hello.

As mentioned in the PR, having a diamond virtual inheritance can cause a wrong
assumption done in contains_type_p. I also decided to rename one argument of the
function as otr_type and outer_type names are very confusing. Apart from what 
was
written in bugzilla I also verified that after the hunk removal, there's no 
situation
on Firefox where the function would return true, which used to return false.

Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.

Ready to be installed?
Martin
>From 47e06bcf33719df390b9c49328235d9cbb48e4a7 Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Thu, 12 Jan 2017 15:55:42 +0100
Subject: [PATCH] Fix wrong assumption in contains_type_p (PR ipa/71207).

gcc/testsuite/ChangeLog:

2017-01-12  Martin Liska  <mli...@suse.cz>

	PR ipa/71207
	* g++.dg/ipa/pr71207.C: New test.

gcc/ChangeLog:

2017-01-12  Martin Liska  <mli...@suse.cz>

	PR ipa/71207
	* ipa-polymorphic-call.c (contains_type_p): Fix wrong
	assumption, add comment and renamed otr_type to inner_type.
---
 gcc/ipa-polymorphic-call.c         | 22 ++++++++++----------
 gcc/testsuite/g++.dg/ipa/pr71207.C | 42 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ipa/pr71207.C

diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
index da64ce4c6e0..c13fc858c86 100644
--- a/gcc/ipa-polymorphic-call.c
+++ b/gcc/ipa-polymorphic-call.c
@@ -446,15 +446,15 @@ no_useful_type_info:
     }
 }
 
-/* Return true if OUTER_TYPE contains OTR_TYPE at OFFSET.
-   CONSIDER_PLACEMENT_NEW makes function to accept cases where OTR_TYPE can
+/* Return true if OUTER_TYPE contains INNER_TYPE at OFFSET.
+   CONSIDER_PLACEMENT_NEW makes function to accept cases where INNER_TYPE can
    be built within OUTER_TYPE by means of placement new.  CONSIDER_BASES makes
-   function to accept cases where OTR_TYPE appears as base of OUTER_TYPE or as
+   function to accept cases where INNER_TYPE appears as base of OUTER_TYPE or as
    base of one of fields of OUTER_TYPE.  */
 
 static bool
 contains_type_p (tree outer_type, HOST_WIDE_INT offset,
-		 tree otr_type,
+		 tree inner_type,
 		 bool consider_placement_new,
 		 bool consider_bases)
 {
@@ -463,18 +463,18 @@ contains_type_p (tree outer_type, HOST_WIDE_INT offset,
   /* Check that type is within range.  */
   if (offset < 0)
     return false;
-  if (TYPE_SIZE (outer_type) && TYPE_SIZE (otr_type)
-      && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST
-      && TREE_CODE (TYPE_SIZE (otr_type)) == INTEGER_CST
-      && wi::ltu_p (wi::to_offset (TYPE_SIZE (outer_type)),
-		    (wi::to_offset (TYPE_SIZE (otr_type)) + offset)))
-    return false;
+
+  /* PR ipa/71207
+     As OUTER_TYPE can be a type which has a diamond virtual inheritance,
+     it's not necessary that INNER_TYPE will fit within OUTER_TYPE with
+     a given offset.  It can happen that INNER_TYPE also contains a base object,
+     however it would point to the same instance in the OUTER_TYPE.  */
 
   context.offset = offset;
   context.outer_type = TYPE_MAIN_VARIANT (outer_type);
   context.maybe_derived_type = false;
   context.dynamic = false;
-  return context.restrict_to_inner_class (otr_type, consider_placement_new,
+  return context.restrict_to_inner_class (inner_type, consider_placement_new,
 					  consider_bases);
 }
 
diff --git a/gcc/testsuite/g++.dg/ipa/pr71207.C b/gcc/testsuite/g++.dg/ipa/pr71207.C
new file mode 100644
index 00000000000..19a03998460
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr71207.C
@@ -0,0 +1,42 @@
+/* PR ipa/71207 */
+/* { dg-do run } */
+
+class Class1
+{
+public:
+  Class1() {};
+  virtual ~Class1() {};
+
+protected:
+  unsigned Field1;
+};
+
+class Class2 : public virtual Class1
+{
+};
+
+class Class3 : public virtual Class1
+{
+public:
+  virtual void Method1() = 0;
+
+  void Method2()
+  {
+    Method1();
+  }
+};
+
+class Class4 : public Class2, public virtual Class3
+{
+public:
+  Class4() {};
+  virtual void Method1() {};
+};
+
+int main()
+{
+  Class4 var1;
+  var1.Method2();
+
+  return 0;
+}
-- 
2.11.0

Reply via email to