re PR ipa/60306 (Incorrect devirtualization "pure virtual method called")
authorJan Hubicka <hubicka@ucw.cz>
Sun, 2 Mar 2014 20:51:48 +0000 (21:51 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 2 Mar 2014 20:51:48 +0000 (20:51 +0000)
PR ipa/60306

Revert:
2013-12-14   Jan Hubicka  <jh@suse.cz>
        PR middle-end/58477
        * ipa-prop.c (stmt_may_be_vtbl_ptr_store): Skip clobbers.

* testsuite/g++.dg/ipa/devirt-29.C: New testcase

From-SVN: r208261

gcc/ChangeLog
gcc/ipa-prop.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/devirt-29.C [new file with mode: 0644]

index 4224c01..b6f1dac 100644 (file)
@@ -1,3 +1,12 @@
+2014-03-02  Jan Hubicka  <hubicka@ucw.cz>
+       
+       PR ipa/60306
+
+       Revert:
+       2013-12-14   Jan Hubicka  <jh@suse.cz>
+        PR middle-end/58477
+        * ipa-prop.c (stmt_may_be_vtbl_ptr_store): Skip clobbers.
+
 2014-03-02  Jon Beniston  <jon@beniston.com>
 
        PR bootstrap/48230
index 368b93b..4fb916a 100644 (file)
@@ -573,8 +573,7 @@ stmt_may_be_vtbl_ptr_store (gimple stmt)
 {
   if (is_gimple_call (stmt))
     return false;
-  else if (gimple_clobber_p (stmt))
-    return false;
+  /* TODO: Skip clobbers, doing so triggers problem in PR60306.  */
   else if (is_gimple_assign (stmt))
     {
       tree lhs = gimple_assign_lhs (stmt);
index b292df2..864057e 100644 (file)
@@ -1,3 +1,8 @@
+2014-03-02  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/60306
+       * testsuite/g++.dg/ipa/devirt-29.C: New testcase
+
 2014-03-02  Bernd Edlinger  <bernd.edlinger@hotmail.de>
 
        PR fortran/60236
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-29.C b/gcc/testsuite/g++.dg/ipa/devirt-29.C
new file mode 100644 (file)
index 0000000..190d9e2
--- /dev/null
@@ -0,0 +1,75 @@
+/* { dg-do run } */
+/* There is a devirtualizable call. In PR60306 we deduced wrong target to cxa_pure_virtual.
+   For gcc 4.10 we temporarily disable the devirtualization.  */
+/* { dg-options "-O3 -std=c++11"  } */
+
+#include <vector>
+
+using std::vector;
+
+class Object 
+{
+public:
+
+  virtual Object* clone() const =0;
+
+  virtual int type() const {return 0;}
+
+  Object& operator=(const Object&) {return *this;}
+
+  Object() {}
+  Object(const Object&) {}
+  virtual ~Object() {}
+};
+
+Object* f(const Object&o)
+{
+  return o.clone();
+}
+
+template<typename T>
+class Box: public Object, public T
+{
+public:
+  Box<T>* clone() const {return new Box<T>(*this);}
+
+  Box<T>& operator=(const Box<T>& t)
+  {
+    T::operator=(t);
+    return *this;
+  }
+
+  Box<T>& operator=(const T& t)
+  {
+    T::operator=(t);
+    return *this;
+  }
+
+  Box() = default;
+  Box(const Box<T>&) = default;
+  explicit Box(const T& t):T(t) {}
+};
+
+template <typename T>
+using Vector = Box<vector<T>>;
+
+typedef Vector<int> OVector;
+
+OVector edges_connecting_to_node(int n)
+{
+  OVector branch_list_;
+  for(int i=0;i<n;i++)
+    branch_list_.push_back(i);
+
+  return branch_list_;
+}
+
+int main(int argc,char* argv[])
+{ 
+  for(int n=0; n < argc; n++)
+  {
+    auto x = edges_connecting_to_node(1);
+    x.clone();
+    f(x);
+  }
+}