Analysis of integer values in C#
note
The functionality described below is only available in .NET/.NET Core and ASP.NET Core projects and requires Smart Mode to be enabled.
JetBrains Fleet can track the flow of integer values through your code and report redundant or possibly erroneous statements. It supports all C# integral numeric types — int
, uint
, byte
, sbyte
, short
, ushort
, long
, and ulong
— and warns you about the following issues:
relational/equality operators that always evaluate to
true
orfalse
,unreachable
switch
cases checkingint
values,meaningless arithmetic operations, such as multiplication by
1
or addition of0
(except literals or constants: JetBrains Fleet assumes that expressions likex + 0
are intentional),possible
int
overflows,possible division by
0
,possible errors in invocations of
System.Math
methods,the above issues in enumeration types with the corresponding underlying types.
JetBrains Fleet narrows down the possible range of values for each integer according to possible outcomes of all statements and expressions that can produce or affect that integer. Let's consider some examples.
JetBrains Fleet can deduce that temp < 0
in the example below will always evaluate to false
because Math.Abs always returns a non-negative value.
void TestInput(int input)
{
var temp = Math.Abs(input);
// do something
if(temp < 0) // Expression is always false
Console.WriteLine("Some output");
}
In the following example, JetBrains Fleet infers that by the last return
, the value of input
is in the range of -100 ... 100
, and when divided by a larger divider
, it will be truncated towards zero.
int TestDivision(int input, int delta)
{
const int divider = 500;
if(input < -100 || input > 100)
return input;
input = input / divider;
// do something
return delta + input; // Addition of 0
}
There are two JetBrains.Annotations attributes ([NonNegativeValue]
and [ValueRange(from, to)]
) for analysis of integer values.
You can use these attributes with type members returning int
and with int
parameters to specify known constraints and thus improve analysis precision.
Here is an example of annotating the method parameter with [NonNegativeValueAttribute] to refine the analysis within the method body. Knowing that the parameter is non-negative, JetBrains Fleet can report all redundant operations on that parameter:
void TestSwitch([NonNegativeValue] int input)
{
var newValue = input switch
{
0 => 1,
-1 => 0, // Case is heuristically unreachable
_ => input,
};
if (input < 0) // Expression is always false
Console.WriteLine("some output");
}
The following example demonstrates how annotating a method can help find redundant checks around its usages:
[ValueRange(1,6)]
int RollDice() => // my random generator
void Play()
{
var firstRoll = RollDice();
if (firstRoll < 1 || firstRoll > 6) // Expression is always false
throw new ArgumentOutOfRangeException();
// roll again
}
Thanks for your feedback!