Farid Zaripov-2 wrote:
> 
>> 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
> void
> __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;
> 
> 

Thanks for looking into it! That's too bad about noreturn. It can help
the compiler generate better code so it would be a shame to have to
remove it. A test case might help us come up with a workaround and get
Microsoft to fix their compiler :)



> 
> 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):
> 
> 
...


> 
> _EXPORT
> 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; ) {
>         --__parent;
>         __adjust_heap (__first, __parent, __dist, *(__first + __parent),
>                        __comp);
>     }
> }
> 
> 

This is close to what I had in mind when I saw the #ifdef but is it
the same thing? IIUC, in the original version, the loop will execute
at least once. In this version, it may not execute at all (i.e., if
__parent is zero). Or does it not matter? If not, this would seem
like an improvement over the original code irrespective of the ICE,
which is exactly what I was hoping for! :)

Martin
-- 
View this message in context: 
http://www.nabble.com/Re%3A--jira--Created%3A-%28STDCXX-1022%29--MSVC-x86---optimized--ICE-in-std%3A%3A__make_heap%28%29-tp20532273p20553378.html
Sent from the stdcxx-dev mailing list archive at Nabble.com.

Reply via email to