New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constant-folding int.MinValue % -1 #27348

Open
jakobbotsch opened this Issue Jun 1, 2018 · 2 comments

Comments

Projects
None yet
4 participants
@jakobbotsch

jakobbotsch commented Jun 1, 2018

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 dotnet/coreclr#18235 (comment), 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?

@gafter

This comment has been minimized.

Show comment
Hide comment
@gafter

gafter Jun 2, 2018

Member

This is a bug.

Member

gafter commented Jun 2, 2018

This is a bug.

@pkulikov

This comment has been minimized.

Show comment
Hide comment
@pkulikov

pkulikov Sep 3, 2018

@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 or long value and the right operand is –1, an
overflow occurs. In a checked context, this causes a System.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.

pkulikov commented Sep 3, 2018

@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 or long value and the right operand is –1, an
overflow occurs. In a checked context, this causes a System.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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment