I can reproduce this too. When an error occurs, the code tests eax to determine whether to output "BUG", which is the same register as for "pos".
17: previous_pos = ++pos;
013C12E5 inc eax
...
21: if (previous_pos == std::string::npos)
00301345 cmp eax, eax
00301347 jne main + 0F6h (0301366h)
However, if you make changes to try to make the optimizer realize that they are different, then the test is different. If I add ++ previous_pos to the end of the loop body, then it uses ecx for previous_pos and the error will disappear:
22: if (previous_pos == std::string::npos)
00361349 cmp ecx, eax
0036134B jne main + 0FAh (036136Ah)
If I changed find to 'pos = buffer.find (' w ', previous_pos); (search from previous_pos instead of pos, which has the same meaning), then it uses ebx, and again the error disappears:
21: if (previous_pos == std::string::npos)
00191345 cmp ebx, eax
00191347 jne main + 0F6h (0191366h)
So, in the original it seems that the optimizer mistakenly decides that it can use eax for both of these variables, despite the string 'pos = buffer.find (' w ', pos); which can set pos to a different value than previous_pos.
mattw source share