2008-02-15 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 15 Feb 2008 15:24:19 +0000 (15:24 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 15 Feb 2008 15:24:19 +0000 (15:24 +0000)
Zdenek Dvorak  <ook@ucw.cz>

PR tree-optimization/35164
* tree-flow.h (stmt_references_abnormal_ssa_name): Declare.
* tree-dfa.c (stmt_references_abnormal_ssa_name): New function.
* tree-ssa-forwprop.c (tree_ssa_forward_propagate_single_use_vars):
Only propagate addresses which do not have abnormal SSA_NAMEs
in their operands.

* g++.dg/torture/pr35164-1.C: New testcase.
* g++.dg/torture/pr35164-2.C: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@132345 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr35164-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/pr35164-2.C [new file with mode: 0644]
gcc/tree-dfa.c
gcc/tree-flow.h
gcc/tree-ssa-forwprop.c

index a82c143..b3075a6 100644 (file)
@@ -1,3 +1,13 @@
+2008-02-15  Richard Guenther  <rguenther@suse.de>
+       Zdenek Dvorak  <ook@ucw.cz>
+
+       PR tree-optimization/35164
+       * tree-flow.h (stmt_references_abnormal_ssa_name): Declare.
+       * tree-dfa.c (stmt_references_abnormal_ssa_name): New function.
+       * tree-ssa-forwprop.c (tree_ssa_forward_propagate_single_use_vars):
+       Only propagate addresses which do not have abnormal SSA_NAMEs
+       in their operands.
+
 2008-02-15  Joseph Myers  <joseph@codesourcery.com>
 
        PR target/35088
index 26b41f8..f5ec2de 100644 (file)
@@ -1,3 +1,10 @@
+2008-02-15  Richard Guenther  <rguenther@suse.de>
+       Zdenek Dvorak  <ook@ucw.cz>
+
+       PR tree-optimization/35164
+       * g++.dg/torture/pr35164-1.C: New testcase.
+       * g++.dg/torture/pr35164-2.C: Likewise.
+
 2008-02-15  Dominique d'Humieres  <dominiq@lps.ens.fr>
 
        PR testsuite/35119
diff --git a/gcc/testsuite/g++.dg/torture/pr35164-1.C b/gcc/testsuite/g++.dg/torture/pr35164-1.C
new file mode 100644 (file)
index 0000000..1704c22
--- /dev/null
@@ -0,0 +1,69 @@
+typedef __SIZE_TYPE__ size_t;
+template<typename _Iterator, typename _Container> class __normal_iterator {
+public:
+  const _Iterator& base() const;
+};
+template<typename _BI1, typename _BI2> inline
+void copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
+  while (__first != __last) *--__result = *--__last;
+}
+template<typename _Tp> struct _Vector_base {
+  struct _Vector_impl { _Tp* _M_finish; };
+  _Vector_impl _M_impl;
+};
+template<typename _Tp > class vector : protected _Vector_base<_Tp> {
+  typedef vector<_Tp> vector_type;
+  typedef _Tp * pointer;
+  typedef _Tp & reference;
+  typedef __normal_iterator<pointer, vector_type> iterator;
+  typedef size_t size_type;
+public:
+  iterator end();
+  void resize(size_type __new_size) { insert(end(), __new_size); }
+  reference operator[](size_type __n);
+  void insert(iterator __position, size_type __n)
+  {
+    pointer __old_finish(this->_M_impl._M_finish);
+    copy_backward(__position.base(), __old_finish - __n, __old_finish);
+  }
+};
+struct A {
+  virtual ~A ();
+  void incRef ();
+  void decRef ();
+};
+struct C : public A {
+  static C *alloc ();
+};
+template <class T> struct B {
+  B () : ptr (T::alloc ()) { }
+  B (T *a_ptr) : ptr (a_ptr) { }
+  ~B () { decRef (); }
+  B& operator= (const B<T>& a) { if (a.get () != this->get ()) { decRef ();
+incRef (); } }
+  template<class U> operator B<U> () const { return B<U> (ptr); }
+  T* operator-> () const { }
+  T* get () const { return ptr; }
+  void decRef () const { if (ptr != 0) ptr->decRef (); }
+  void incRef () const { if (ptr != 0) ptr->incRef (); }
+  T *ptr;
+};
+struct D : public C {
+  template <class T> inline void foo (const B<T> & x) { d.resize (1); d[0] = x;
+}
+  vector<B <C> > d;
+};
+struct E : public C {
+  static E *alloc ();
+};
+struct F : public D {
+  static F *alloc ();
+};
+void foo (vector<B<D> > & x) {
+  for (int i = 0; i < 2; ++i)
+    {
+      B<F> l;
+      B<E> m;
+      l->foo (m);
+    }
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr35164-2.C b/gcc/testsuite/g++.dg/torture/pr35164-2.C
new file mode 100644 (file)
index 0000000..463cad7
--- /dev/null
@@ -0,0 +1,27 @@
+struct __shared_count {
+    __shared_count() { _M_pi = new int; }
+    int * _M_pi;
+};
+template<typename _Tp>
+class __shared_ptr {
+public:
+    __shared_ptr(_Tp* __p);
+    void reset(int * __p) {
+        __shared_ptr(__p).swap(*this);
+    }
+    void swap(__shared_ptr<_Tp>& __other) {
+        __other._M_refcount._M_pi = _M_refcount._M_pi;
+    }
+    __shared_count _M_refcount;
+};
+template<typename _Tp> class shared_ptr : public __shared_ptr<_Tp> {};
+int main() {
+    for (shared_ptr<int> *iter;;)
+    {
+        try {
+            (iter++)->reset(new int);
+        }
+        catch (...) {
+        }
+    }
+}
index f79df0b..346f6f3 100644 (file)
@@ -1028,3 +1028,21 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
   return exp;
 }
 
+/* Returns true if STMT references an SSA_NAME that has
+   SSA_NAME_OCCURS_IN_ABNORMAL_PHI set, otherwise false.  */
+
+bool
+stmt_references_abnormal_ssa_name (tree stmt)
+{
+  ssa_op_iter oi;
+  use_operand_p use_p;
+
+  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, oi, SSA_OP_USE)
+    {
+      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (use_p)))
+       return true;
+    }
+
+  return false;
+}
+
index adc2508..286c60b 100644 (file)
@@ -822,6 +822,7 @@ extern void find_new_referenced_vars (tree *);
 extern tree make_rename_temp (tree, const char *);
 extern void set_default_def (tree, tree);
 extern tree gimple_default_def (struct function *, tree);
+extern bool stmt_references_abnormal_ssa_name (tree);
 
 /* In tree-phinodes.c  */
 extern void reserve_phi_args_for_new_edge (basic_block);
index 2da17c8..91bd617 100644 (file)
@@ -968,7 +968,8 @@ tree_ssa_forward_propagate_single_use_vars (void)
                      && types_compatible_p (TREE_TYPE (TREE_TYPE (TREE_OPERAND (rhs, 0))),
                                             TREE_TYPE (TREE_TYPE (rhs)))))
                {
-                 if (forward_propagate_addr_expr (lhs, rhs))
+                 if (!stmt_references_abnormal_ssa_name (stmt)
+                     && forward_propagate_addr_expr (lhs, rhs))
                    {
                      release_defs (stmt);
                      todoflags |= TODO_remove_unused_locals;