http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50325

--- Comment #4 from Andreas Krebbel <krebbel at gcc dot gnu.org> 2011-09-14 
07:20:14 UTC ---
I've looked into the 22_locale/money_get/get/char/13.cc failure.

The problem is a miscompilation of locale-inst.cc in libstdc++.

Source:

template<typename _CharT, typename _InIter>
    _InIter
    money_get<_CharT, _InIter>::
    do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
       ios_base::iostate& __err, long double& __units) const
    {
      string __str;
      __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
                 : _M_extract<false>(__beg, __end, __io, __err, __str);
      std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
      return __beg;
    }

The result of _M_extract is copied into the return ptr field of the
function.  This assignment copies 12 bytes:

MEM[(struct iter_type *)&__beg] = MEM[(struct iter_type *)&D.23511];

expand_assignement expands this using store_field. However
store_bit_field_1 does not seem to handle BLKmode copies correctly for
byte big endian targets if the source cannot exactly be covered by
word mode operands. It calls itself recursively for the last chunk with:

store_bit_field_1 (str_rtx=0x3fff6528a38, bitsize=32, bitnum=64,
bitregion_start=0, bitregion_end=0, 
    fieldmode=DImode, value=0x3fff6528ab0, fallback_p=true)

with value being (subreg:DI (reg:TI 70) 8)

But copying 4 bytes from that value on a big endian target results in
a src value of (subreg:DI (reg:TI 70) 12) so the wrong word is being
copied here.

Reply via email to