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.