re PR middle-end/45877 (invalid write in gimplify_and_update_call_from_tree)
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. * g++.dg/torture/pr45877.C: New testcase. From-SVN: r164984
This commit is contained in:
parent
ce417b8f3f
commit
6e57232622
4 changed files with 167 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
141
gcc/testsuite/g++.dg/torture/pr45877.C
Normal file
141
gcc/testsuite/g++.dg/torture/pr45877.C
Normal file
|
@ -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>();
|
||||
}
|
Loading…
Add table
Reference in a new issue