aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimple-fold.c16
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr45877.C141
4 files changed, 167 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a949d2e..c068674 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 0a6c746..d412eb2 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1a21e0e..cfa09f7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..9af6ae9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr45877.C
@@ -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>();
+}