From 6e5723262255ea4d43d14d7c959e4dcc28cd01c3 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Tue, 5 Oct 2010 10:37:12 +0000 Subject: [PATCH] re PR middle-end/45877 (invalid write in gimplify_and_update_call_from_tree) 2010-10-05 Richard Guenther 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. From-SVN: r164984 --- gcc/ChangeLog | 6 ++ gcc/gimple-fold.c | 16 +++- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/g++.dg/torture/pr45877.C | 141 +++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr45877.C 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 + + 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 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 + + PR middle-end/45877 + * g++.dg/torture/pr45877.C: New testcase. + 2010-10-04 Jakub Jelinek 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 class allocator; + template struct char_traits; + template, + typename _Alloc = allocator<_CharT> > + class basic_string; + typedef basic_string string; + template struct pair { }; + template class allocator { }; + template + struct binary_function { + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; + }; + template + 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 + 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 map_type; +class AnyTypeWithOutCheck { }; +typedef AnyTypeWithOutCheck AnyType; +template AnyTypeWithOutCheck inline SetAny(const T & x) +{ + AnyTypeWithOutCheck any; + memcpy(&any,&x,sizeof(x)); +} +template 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 +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(static_cast(C::f( GetAny((*a)(s)), + GetAny((*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 KN_: public ShapeOfArray { }; +template struct affectation: binary_function { }; +template struct set_A_BI +: public binary_function,pair, KN_ > *,KN_ > +{ + static KN_ f(const KN_ & a, pair, KN_ > * const & b); +}; +template struct set_AI_B +: public binary_function, KN_ > * ,KN_, NothingType > +{ + static NothingType f( pair, KN_ > * const & b,const KN_ & a); +}; +template void ArrayOperator() +{ + TheOperators->Add("=", new OneBinaryOperator > >, + new OneBinaryOperator > >); +} +void initArrayOperatorlong() { + ArrayOperator(); +} -- 2.7.4