When enabling the overflow/underflow compiler flag, there is a case when JIT generate wrong code. basically we have a method
internal unsafe void AdjustBytes(int count)
{
_bytes += count;
}
in the file
https://github.com/dotnet/corefx/blob/10733b7bb84d6132f4ac6fd83f3405f3ebd689a6/src/System.Text.Encoding.CodePages/src/System/Text/EncodingCharBuffer.cs#L91
When compiling with overflow flag on, the jit will produce the following
00007FFF46E67D50 push rbp
00007FFF46E67D51 push rdi
00007FFF46E67D52 push rsi
00007FFF46E67D53 sub rsp,30h
00007FFF46E67D57 mov rbp,rsp
00007FFF46E67D5A xor eax,eax
00007FFF46E67D5C mov qword ptr [rbp+28h],rax
00007FFF46E67D60 mov qword ptr [rbp+50h],rcx
00007FFF46E67D64 mov dword ptr [rbp+58h],edx
00007FFF46E67D67 cmp dword ptr [7FFF46DFB728h],0
00007FFF46E67D6E je 00007FFF46E67D75
00007FFF46E67D70 call 00007FFFA65B0EB0
00007FFF46E67D75 nop
_bytes += count;
00007FFF46E67D76 mov rax,qword ptr [rbp+50h]
00007FFF46E67D7A mov edx,dword ptr [rbp+58h]
00007FFF46E67D7D mov edx,edx
00007FFF46E67D7F add rdx,qword ptr [rax+48h]
00007FFF46E67D83 jae 00007FFF46E67D8A
00007FFF46E67D85 call 00007FFFA65AFBD0
00007FFF46E67D8A mov rax,qword ptr [rbp+50h]
00007FFF46E67D8E mov qword ptr [rax+48h],rdx
}
00007FFF46E67D92 nop
00007FFF46E67D93 lea rsp,[rbp+30h]
00007FFF46E67D97 pop rsi
00007FFF46E67D98 pop rdi
00007FFF46E67D99 pop rbp
00007FFF46E67D9A ret
you can notice the operations neglect the sign. so if someone pass negative number to the method we'll end up with wrong result. if we compile with overflow flag off, JIT produce the following right code:
00007FFF46E877B0 push rbp
00007FFF46E877B1 push rdi
00007FFF46E877B2 push rsi
00007FFF46E877B3 sub rsp,30h
00007FFF46E877B7 mov rbp,rsp
00007FFF46E877BA xor eax,eax
00007FFF46E877BC mov qword ptr [rbp+28h],rax
00007FFF46E877C0 mov qword ptr [rbp+50h],rcx
00007FFF46E877C4 mov dword ptr [rbp+58h],edx
00007FFF46E877C7 cmp dword ptr [7FFF46E1B728h],0
00007FFF46E877CE je 00007FFF46E877D5
00007FFF46E877D0 call 00007FFFA65B0EB0
00007FFF46E877D5 nop
_bytes += count;
00007FFF46E877D6 mov eax,dword ptr [rbp+58h]
00007FFF46E877D9 movsxd rax,eax
00007FFF46E877DC mov rdx,qword ptr [rbp+50h]
00007FFF46E877E0 add qword ptr [rdx+48h],rax
}
00007FFF46E877E4 nop
00007FFF46E877E5 lea rsp,[rbp+30h]
00007FFF46E877E9 pop rsi
00007FFF46E877EA pop rdi
00007FFF46E877EB pop rbp
00007FFF46E877EC ret
to repro the issue, on corefx repo do the following:
you'll get one test failed because of the wrong code generated for the AdjustBytes method in the library System.Text.Encoding.CodePages
dotnet/corefx#16160
When enabling the overflow/underflow compiler flag, there is a case when JIT generate wrong code. basically we have a method
in the file
https://github.com/dotnet/corefx/blob/10733b7bb84d6132f4ac6fd83f3405f3ebd689a6/src/System.Text.Encoding.CodePages/src/System/Text/EncodingCharBuffer.cs#L91
When compiling with overflow flag on, the jit will produce the following
you can notice the operations neglect the sign. so if someone pass negative number to the method we'll end up with wrong result. if we compile with overflow flag off, JIT produce the following right code:
to repro the issue, on corefx repo do the following:
you'll get one test failed because of the wrong code generated for the AdjustBytes method in the library System.Text.Encoding.CodePages
dotnet/corefx#16160