I have what I'm pretty sure is a bug in the optimizer in Visual studio 2005. The problem is with an STL map.
Here's the relevant code:
MyMapIterator myIt = m_myMap.find(otherID);
if (myIt != m_myMap.end() && myIt->second.userStatus == STATUS_A)
{
//Prints stuff. No side-effects whatsoever.
}
else if (myIt != m_myMap.end() && myIt->second.userStatus == STATUS_B && myIt->second.foo == FOO_A)
{
//Prints stuff. No side-effects whatsoever.
}
else if (myIt != m_myMap.end() && myIt->second.userStatus == STATUS_B && myIt->second.foo == FOO_B && /*other meaningless conditions */)
{
//Prints stuff. No side-effects whatsoever.
}
Works flawlessly in debug, used to crash in release, and disabling global optimizations "fixed it" Now, nothing works. I get a:
Microsoft Visual Studio C Runtime Library has detected a fatal error in [...]
Press Break to debug the program or Continue to terminate the program.
This happens on the first MyMapIterator::operator-> of the last else if
The map is empty, I know that find should have returned end(), The first two comparisons to that effect work. But somehow, the third time 'myIt != m_myMap.end()' returns true, and the right side of the && is executed.
Various other places fail like this with a variant of 'myIt != m_myMap.end()' returning true in that same file, but this is, to me, the one that rules out most other possibilities. I used to think it was a buffer overflow that was stomping on my map, but take a look back at the code. I am positive that no other thread is stomping on it, and this is 100% reproductible.
So, what do I do from here. This is not performance sensitive in the slightest. I just need it to work as it should. Any option is acceptable. Yes I know I could surround the whole thing with the iterator equality check and it isn't the nicest code. The point is, it should still work, and if that fails, anything else can.
EDIT
The last else-if doesn't generate any jump !
if (myIt != m_myMap.end() && myIt->second.userStatus == STATUS_A)
009270BE mov ecx,dword ptr [this]
009270C4 add ecx,0Ch
009270C7 lea eax,[ebp-90h]
009270CD call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::end (8A21E0h)
009270D2 mov esi,eax
009270D4 lea edi,[myIt]
009270D7 call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::const_iterator::operator!= (8A2220h)
009270DC movzx ecx,al
009270DF test ecx,ecx
009270E1 je lux::Bar::DoStuff+0E4h (927154h)
009270E3 lea esi,[myIt]
009270E6 call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::iterator::operator-> (8A21F0h)
009270EB cmp dword ptr [eax+8],1
009270EF jne lux::Bar::DoStuff+0E4h (927154h)
{
Stuff
}
else if (myIt != m_myMap.end() && myIt->second.userStatus == STATUS_B)
00927154 mov ecx,dword ptr [this]
0092715A add ecx,0Ch
0092715D lea eax,[ebp-98h]
00927163 call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::end (8A21E0h)
00927168 mov esi,eax
0092716A lea edi,[myIt]
0092716D call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::const_iterator::operator!= (8A2220h)
00927172 movzx edx,al
00927175 test edx,edx
00927177 je lux::Bar::DoStuff+17Ah (9271EAh)
00927179 lea esi,[myIt]
0092717C call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::iterator::operator-> (8A21F0h)
00927181 cmp dword ptr [eax+8],2
00927185 jne lux::Bar::DoStuff+17Ah (9271EAh)
{
//Stuff
}
else if (myIt != m_myMap.end() && myIt->second.userStatus == STATUS_C)
009271EA mov ecx,dword ptr [this]
009271F0 add ecx,0Ch
009271F3 lea eax,[ebp-0A0h]
009271F9 call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::end (8A21E0h)
009271FE mov esi,eax
00927200 lea edi,[myIt]
00927203 call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::const_iterator::operator!= (8A2220h)
00927208 lea esi,[myIt]
0092720B call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::iterator::operator-> (8A21F0h)
{
//Stuff in the condition and after