stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Farid Zaripov <>
Subject Re: [jira] Created: (STDCXX-1022) [MSVC x86 / optimized] ICE in std::__make_heap()
Date Mon, 17 Nov 2008 16:27:23 GMT
> Did you happen to reduce this to a small test case and send
> it to Microsoft?

  Not yet. It's difficult to create the small test.

> Do you see the ICE in a specific test (or example), maybe only for a
> specific instantiation of the template, or does it happen regardless
> of the actual types of the template arguments?

  Today I've made some investigations:

1. the 25.heap, 25.partial.sort and 25.sort tests from trunk and 4.3.x branch
are compiled withoud ICE;

2. the only difference between preprocessed 25.heap tests from 4.2.x branch and trunk is

Comparing files 42x.i and trunk.i
***** 42x.i
void  __declspec (noreturn)
__rw_assert_fail (const char*, const char*, int, const char*)
***** trunk.i
__rw_assert_fail (const char*, const char*, int, const char*)

3. removing _RWSTD_NORETURN from declaration of the __rw_assert_fail() eliminates
the ICE in tests from 4.2.x branch;

4. The __rw_assert_fail() is used in RandomAccessIter methods thus RW_ASSERT macro;

  So I guess, that MSVC issues ICE when processing "infinite" for-loop (loop without condition)
with __declspec (noreturn) function inside the loop.

> Btw., the reason I ask is so we can come up with a better/cleaner
> workaround, hopefully one that will be as efficient as the original
> code and won't need an #ifdef.

  I've just added condition in for-loop, to make the loop finite.
We can rewrite the loop the same way, as it's implemented in Dinkumware STL
(it's also fixes the ICE):

template<class _RanIt,
        class _Diff,
        class _Ty,
        class _Pr> inline
        void _Make_heap(_RanIt _First, _RanIt _Last, _Pr _Pred, _Diff *, _Ty *)
        {       // make nontrivial [_First, _Last) into a heap, using _Pred
        _Diff _Bottom = _Last - _First;
        for (_Diff _Hole = _Bottom / 2; 0 < _Hole; )
                {       // reheap top half, bottom to top
                std::_Adjust_heap(_First, _Hole, _Bottom,
                        _Ty(*(_First + _Hole)), _Pred);

template <class _RandomAccessIter, class _Compare, class _Dist>
void __make_heap (_RandomAccessIter __first, _RandomAccessIter __last,
                  _Compare __comp, _Dist*)
    _RWSTD_ASSERT_RANGE (__first, __last);

    const _Dist __dist = __last - __first;

    for (_Dist __parent = __dist / 2; 0 < __parent; ) {
        __adjust_heap (__first, __parent, __dist, *(__first + __parent),


View raw message