OSDN Git Service

2010-10-05 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 5 Oct 2010 10:37:12 +0000 (10:37 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 5 Oct 2010 10:37:12 +0000 (10:37 +0000)
PR middle-end/45877
* gimple-fold.c (gimplify_and_update_call_from_tree): Handle
case where gimplification optimizes away the stmt.

* g++.dg/torture/pr45877.C: New testcase.

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

gcc/ChangeLog
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr45877.C [new file with mode: 0644]

index a949d2e..c068674 100644 (file)
@@ -1,3 +1,9 @@
+2010-10-05  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/45877
+       * gimple-fold.c (gimplify_and_update_call_from_tree): Handle
+       case where gimplification optimizes away the stmt.
+
 2010-10-04  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/45849
index 0a6c746..d412eb2 100644 (file)
@@ -932,7 +932,21 @@ gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
   push_gimplify_context (&gctx);
 
   if (lhs == NULL_TREE)
-    gimplify_and_add (expr, &stmts);
+    {
+      gimplify_and_add (expr, &stmts);
+      /* We can end up with folding a memcpy of an empty class assignment
+        which gets optimized away by C++ gimplification.  */
+      if (gimple_seq_empty_p (stmts))
+       {
+         if (gimple_in_ssa_p (cfun))
+           {
+             unlink_stmt_vdef (stmt);
+             release_defs (stmt);
+           }
+         gsi_remove (si_p, true);
+         return;
+       }
+    }
   else
     tmp = get_initialized_tmp_var (expr, &stmts, NULL);
 
index 1a21e0e..cfa09f7 100644 (file)
@@ -1,3 +1,8 @@
+2010-10-05  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/45877
+       * g++.dg/torture/pr45877.C: New testcase.
+
 2010-10-04  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/45849
diff --git a/gcc/testsuite/g++.dg/torture/pr45877.C b/gcc/testsuite/g++.dg/torture/pr45877.C
new file mode 100644 (file)
index 0000000..9af6ae9
--- /dev/null
@@ -0,0 +1,141 @@
+// { dg-do compile }
+
+namespace std __attribute__ ((__visibility__ ("default")))
+{
+  typedef __SIZE_TYPE__ size_t;
+  template<typename _Alloc>     class allocator;
+  template<class _CharT>     struct char_traits;
+  template<typename _CharT, typename _Traits = char_traits<_CharT>,
+      typename _Alloc = allocator<_CharT> >
+         class basic_string;
+  typedef basic_string<char> string;
+  template<class _T1, class _T2>     struct pair     { };
+  template<typename _Tp>     class allocator    { };
+  template<typename _Arg1, typename _Arg2, typename _Result>
+      struct binary_function     {
+         typedef _Arg1 first_argument_type;
+         typedef _Arg2 second_argument_type;
+         typedef _Result result_type;
+      };
+  template<typename _CharT, typename _Traits, typename _Alloc>
+  class basic_string {
+  public:
+      basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
+  };
+  class type_info   {
+  public:
+      const char* name() const;
+  };
+  extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__, __artificial__))
+  void * memcpy (void *__restrict __dest, __const void *__restrict __src, size_t __len) throw ()
+  {
+      return __builtin___memcpy_chk (__dest, __src, __len, __builtin_object_size (__dest, 0));
+  }
+  template <typename _Key, typename _Tp >
+  class map {
+      typedef _Key key_type;
+      typedef _Tp mapped_type;
+  public:
+      mapped_type&       operator[](const key_type& __k);
+  };
+}
+class CodeAlloc { };
+using namespace std;
+typedef void *Stack;
+class basicForEachType;
+typedef const basicForEachType * aType;
+extern map<const string,basicForEachType *> map_type;
+class AnyTypeWithOutCheck { };
+typedef AnyTypeWithOutCheck AnyType;
+template<typename T> AnyTypeWithOutCheck inline SetAny(const T & x)
+{
+  AnyTypeWithOutCheck any;
+  memcpy(&any,&x,sizeof(x));
+}
+template<typename T> const T& GetAny(const AnyTypeWithOutCheck & x);
+class E_F0;
+class C_F0;
+class Polymorphic;
+typedef E_F0 * Expression;
+class basicAC_F0;
+extern Polymorphic * TheOperators, * TheRightOperators;
+class basicForEachType : public CodeAlloc {
+public:
+    virtual C_F0 CastTo(const C_F0 & e) const ;
+};
+class E_F0 :public CodeAlloc    {
+public:
+    virtual AnyType operator()(Stack) const =0;
+};
+class E_F0mps : public E_F0 {
+};
+class ArrayOfaType : public CodeAlloc{
+protected:
+    aType * t;
+};
+class OneOperator : public ArrayOfaType {
+public:
+    OneOperator(aType rr,aType a,aType b);
+    virtual E_F0 * code(const basicAC_F0 &) const =0;
+};
+class Polymorphic: public E_F0mps {
+public:
+    void Add(const char * op,OneOperator * p0 ,OneOperator * p1=0) const;
+};
+class C_F0 {
+public:
+    operator E_F0 * () const;
+};
+class basicAC_F0 {
+public:
+    const C_F0 & operator [] (int i) const;
+};
+struct OneBinaryOperatorMI { };
+struct evalE_F2 { };
+template<typename C,class MI=OneBinaryOperatorMI,class MIx=evalE_F2 >
+class OneBinaryOperator : public OneOperator
+{
+  typedef typename C::result_type R;
+  typedef typename C::first_argument_type A;
+  typedef typename C::second_argument_type B;
+  aType t0,t1;
+  class Op : public E_F0 {
+      Expression a,b;
+  public:
+      AnyType operator()(Stack s) const {
+         return SetAny<R>(static_cast<R>(C::f( GetAny<A>((*a)(s)),
+                                               GetAny<B>((*b)(s)))));
+      }
+      Op(Expression aa,Expression bb) : a(aa),b(bb) { }
+  };
+public:
+  E_F0 * code(const basicAC_F0 & args) const   {
+      return new Op(t0->CastTo(args[0]),t1->CastTo(args[1]));
+  }
+  OneBinaryOperator()
+      : OneOperator(map_type[typeid(R).name()],
+                   map_type[typeid(A).name()],
+                   map_type[typeid(B).name()]), t0(t[0]), t1(t[1]) { }
+};
+struct NothingType { };
+class ShapeOfArray{ };
+template<class R> class KN_: public ShapeOfArray { };
+template <class T> struct affectation: binary_function<T, T, T> { };
+template<class K,class L,class OP> struct set_A_BI
+: public binary_function<KN_<K>,pair<KN_<K>, KN_<L> > *,KN_<K> >
+{
+  static KN_<K> f(const KN_<K> & a, pair<KN_<K>, KN_<L> > * const & b);
+};
+template<class K,class L,class OP> struct set_AI_B
+: public binary_function<pair<KN_<K>, KN_<L> > * ,KN_<K>, NothingType >
+{
+  static NothingType f( pair<KN_<K>, KN_<L> > * const & b,const KN_<K> & a);
+};
+template<class K,class Z> void ArrayOperator()
+{
+  TheOperators->Add("=", new OneBinaryOperator<set_A_BI< K,Z,affectation<K> > >,
+                   new OneBinaryOperator<set_AI_B< K,Z,affectation<K> > >);
+}
+void initArrayOperatorlong() {
+    ArrayOperator<long,long>();
+}