This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix PR ipa/67056


Hi,
this patch fixes a thinko in possible_placement_new which derives that placement
new can not happen before beggining of the memory location of the known type.
While analysitng the testcase I found that check_stmt_for_type_change is bit
stupid to stop on first construction found.  In case the constructor call is
not even polymorphic, we won't derive any useful context.  It is better to
continue the walk and look for polymorphic constructor where we can derive
at least the speculative outer type.

Bootstrapped/regtested x86_64-linux, will commit it shortly.  The patch should
be safe to backport to GCC-5 branch after some time.  The second hunk is not
really neede for correctness, but I think we could include it in backport, too.
Switching to speculative propagation ought not trigger wrong code.

	PR ipa/67056
	* ipa-polymorphic-call.c (possible_placement_new): If cur_offset
	is negative we don't know the type.
	(check_stmt_for_type_change): Skip constructors of non-polymorphic
	types as those won't help devirutalization.
	* g++.dg/ipa/pr67056.C: New testcase.

Index: ipa-polymorphic-call.c
===================================================================
--- ipa-polymorphic-call.c	(revision 229133)
+++ ipa-polymorphic-call.c	(working copy)
@@ -99,6 +99,8 @@ bool
 possible_placement_new (tree type, tree expected_type,
 			HOST_WIDE_INT cur_offset)
 {
+  if (cur_offset < 0)
+    return true;
   return ((TREE_CODE (type) != RECORD_TYPE
 	   || !TYPE_BINFO (type)
 	   || cur_offset >= POINTER_SIZE
@@ -1418,7 +1420,21 @@ check_stmt_for_type_change (ao_ref *ao A
 	    && TYPE_SIZE (type)
 	    && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
 	    && tree_fits_shwi_p (TYPE_SIZE (type))
-	    && tree_to_shwi (TYPE_SIZE (type)) + offset > tci->offset)
+	    && tree_to_shwi (TYPE_SIZE (type)) + offset > tci->offset
+	    /* Some inlined constructors may look as follows:
+		  _3 = operator new (16);
+		  MEM[(struct  &)_3] ={v} {CLOBBER};
+		  MEM[(struct CompositeClass *)_3]._vptr.CompositeClass
+		    = &MEM[(void *)&_ZTV14CompositeClass + 16B];
+		  _7 = &MEM[(struct CompositeClass *)_3].object;
+		  EmptyClass::EmptyClass (_7);
+
+	       When determining dynamic type of _3 and because we stop at first
+	       dynamic type found, we would stop on EmptyClass::EmptyClass (_7).
+	       In this case the emptyclass is not even polymorphic and we miss
+	       it is contained in an outer type that is polymorphic.  */
+
+	    && (tci->offset == offset || contains_polymorphic_type_p (type)))
 	  {
 	    record_known_type (tci, type, tci->offset - offset);
 	    return true;
Index: testsuite/g++.dg/ipa/pr67056.C
===================================================================
--- testsuite/g++.dg/ipa/pr67056.C	(revision 0)
+++ testsuite/g++.dg/ipa/pr67056.C	(revision 0)
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-std=c++11 -O3 -fdump-ipa-cp"  } */
+/* { dg-additional-options "-fPIC" { target fpic } } */
+#include <memory>
+
+class EmptyClass {
+public:
+    EmptyClass();
+};
+
+EmptyClass::EmptyClass() {
+}
+
+class CompositeClass {
+public:
+    CompositeClass() {}
+    virtual ~CompositeClass() {}
+    EmptyClass object;
+    bool bool1;
+    bool bool2;
+};
+
+bool boolFunc() {
+    return true;
+}
+
+static bool staticBoolFunc(CompositeClass * ptr) {
+    std::unique_ptr<CompositeClass> up(ptr);
+    (void)up;
+
+    return boolFunc();
+}
+
+int main(int, char **) {
+    staticBoolFunc(new CompositeClass);
+    return 0;
+}
+
+/* { dg-final { scan-ipa-dump "Speculative outer type:struct CompositeClass" "cp"  } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]