Skip to content
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

Fix S2583: Rule should consider Nullable<bool> values #152

Closed
Evangelink opened this issue Mar 30, 2017 · 2 comments
Closed

Fix S2583: Rule should consider Nullable<bool> values #152

Evangelink opened this issue Mar 30, 2017 · 2 comments
Assignees
Labels
Type: False Positive Rule IS triggered when it shouldn't be.
Milestone

Comments

@Evangelink
Copy link
Contributor

The following code generates a false positive:

bool? x = null;
if (x == true)
{
}
else if (x == false) // FP
{
}
@Evangelink Evangelink added the Type: False Positive Rule IS triggered when it shouldn't be. label Mar 30, 2017
@Evangelink Evangelink added this to the 6.0 milestone Mar 30, 2017
@Evangelink
Copy link
Contributor Author

The problem is that we set a true or false constraint on SV_x when a constraint is set on x == true, however there's a third option that the x == true is false due to x being null, and == being the lifted operator.

@tamasvajk
Copy link
Contributor

@Evangelink, @valhristov This is one of the bigger bugs that I left behind. I started fixing it in https://github.com/tamasvajk/sonar-csharp/tree/feature/152, but I rarely find the time to work on it.

As I see, this problem is not just about Nullable<bool>, but nullables altogether.

x = GetNullableInt();
if (x > 5)
{
}
else if (x <= 5) // seemingly always true, but if x is null, then > and <= returns false
{
}

I think one way to solve this issue is to

  1. introduce a NullableSymbolicValue, and
  2. in operations (binary and unary symbolic values) check if any of the operands is NullableSymbolicValue, and if so, then the operation is a lifted op, and should behave accordingly.

Branch implements point 1. Point 2 is a bit tedious, and before I got there I realized that this solution leads a bit too far, namely (implicit) type changes and casts should be handled in some form:

Currently, for int? i = (int?)5; the data flow engine assigns the same SV to 5, (int?)5 and i. But from now on we'd need not null SV_1 for 5, and not null NullableSV_2 for the other two. There are multiple forms of this problem:

  • int? i = 5;, the same as above.
  • int? i = null;, where SV_null needs to be differentiated from NullableSV_1 with null constraint.

So this note is just to let you know that the branch is there, and could be continued, but before that some decision needs to be made. (And I guess, this should not come from a contributor.)
Also, I would be interested how the JS team handles type changes. I'm guessing (I vaguely remember) they are assigning "type" constraints to symbolic values. Maybe that's the way to go here too, but introducing a dedicated SV type for Nullable<T> seemed more straight forward for a statically typed language.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: False Positive Rule IS triggered when it shouldn't be.
Projects
None yet
Development

No branches or pull requests

4 participants