We ran across an optimization bug in our program when using x64 and the following optimization flags: /O2 /Ob1 /Oi /Ot. Our function is recursive and manipulates a global object. It seems similar to bug ID 678200. However, my example function requires somewhat irrelevant operations, otherwise the bug will disappear. For example, if the std::vector is removed, then correct assembly is generated. This is similar behavior to an earlier bug that I submitted where register allocation was not working properly.
In my example, I analyzed the assembly and noticed that it produces this when it compares the variables at the bottom of the DoSomething function:
if( InstanceState.SavedData != InstanceState.Instance->Data )
000000013F26112C mov eax,dword ptr [Instance+8 (13F263660h)]
000000013F261132 cmp eax,eax
000000013F261134 je DoSomething+0E2h (13F261142h)
The cmp is clearly wrong as the data has changed in the global variable. ResetData should be called in the outermost DoSomething call.
Some final notes:
This code also doesn't work in VS 2008 and 2011 Beta.
Win32 will produce correct assembly.
/Ob0 will produce correct assembly (presumably because the std::vector functions aren't inlined now).