Constant-folding int.MinValue % -1
jakobbotsch opened this issue · comments
The following behavior seems strange to me:
int val = int.MinValue % -1; // constant-folded to 0
val = int.MinValue;
val %= -1; // throws OverflowException at runtime
Quoting @mikedn in https://github.com/dotnet/coreclr/issues/18235#issuecomment-393963856, the spec says:
If the left operand is the smallest int or long value and the right operand is -1, a System.OverflowException is thrown. In no case does x % y throw an exception where x / y would not throw an exception.
Is Roslyn supposed to constant-fold int.MinValue % -1
to 0
rather than give an overflow diagnostic like in other situations?
This is a bug.
@gafter I can observe the similar behavior not only for the remainder operator, but for the division as well:
unchecked
{
Console.WriteLine(int.MinValue / -1); // outputs -2147483648
int val = int.MinValue;
val /= -1; // throws OverflowException
}
Should it be the separate issue?
In this case both outputs are according to the spec:
If the left operand is the smallest representable
int
orlong
value and the right operand is–1
, an
overflow occurs. In a checked context, this causes aSystem.ArithmeticException
(or a subclass
thereof) to be thrown. In an unchecked context, it is implementation-defined as to whether a
System.ArithmeticException
(or a subclass thereof) is thrown or the overflow goes unreported
with the resulting value being that of the left operand.
The issue is that they are not the same.