Tested on x86_64-unknown-linux-gnu, applied as obvious. Richard.
2011-12-06 Richard Guenther <rguent...@suse.de> PR middle-end/51436 * gimple-fold.c (gimplify_and_update_call_from_tree): Guard vdef check for the fact we do not have virtual operands when not optimizing. * g++.dg/torture/pr51436.C: New testcase. Index: gcc/gimple-fold.c =================================================================== *** gcc/gimple-fold.c (revision 182041) --- gcc/gimple-fold.c (working copy) *************** gimplify_and_update_call_from_tree (gimp *** 600,606 **** else vdef = make_ssa_name (gimple_vop (cfun), new_stmt); gimple_set_vdef (new_stmt, vdef); ! if (TREE_CODE (vdef) == SSA_NAME) SSA_NAME_DEF_STMT (vdef) = new_stmt; laststore = new_stmt; } --- 600,606 ---- else vdef = make_ssa_name (gimple_vop (cfun), new_stmt); gimple_set_vdef (new_stmt, vdef); ! if (vdef && TREE_CODE (vdef) == SSA_NAME) SSA_NAME_DEF_STMT (vdef) = new_stmt; laststore = new_stmt; } Index: gcc/testsuite/g++.dg/torture/pr51436.C =================================================================== *** gcc/testsuite/g++.dg/torture/pr51436.C (revision 0) --- gcc/testsuite/g++.dg/torture/pr51436.C (revision 0) *************** *** 0 **** --- 1,60 ---- + /* { dg-do compile } */ + + typedef __SIZE_TYPE__ size_t; + extern "C" void *memcpy (void *, __const void *, size_t); + template < class Dest, class Source > struct BitCastHelper { + static Dest cast (const Source & source) __attribute__ ((always_inline)) { + Dest dest; + memcpy (0, &source, sizeof dest); + } + }; + template < class Dest, class Source > Dest BitCast (Source) + { + BitCastHelper < Dest, Source >::cast (0); + } + + class MaybeObject + { + }; + class Object:MaybeObject + { + public: + static Object *cast (Object *) { + } + }; + class HeapObject:public Object + { + }; + class String:public HeapObject + { + }; + class ExternalString:public String + { + }; + class ExternalTwoByteString:public ExternalString + { + }; + + template < typename T > class Handle + { + public: + Handle () { + } + T *operator* () const; + template < class S > static Handle < T > cast (Handle < S > that) { + T::cast (*that); + } + T **location_; + }; + + template < typename T > T * Handle < T >::operator* () const + { + *BitCast < T ** >(location_); + } + + void + TestCharacterStream () + { + Handle < String > uc16_string; + Handle < ExternalTwoByteString >::cast (uc16_string); + }