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 FP: Change this condition so that it does not always evaluate to 'True' #9676

Closed
marco-carvalho opened this issue Oct 2, 2024 · 10 comments
Labels
Area: C# C# rules related issues. Area: CFG/SE CFG and SE related issues. Area: VB.NET VB.NET rules related issues. Type: CFG/SE FPs Rule IS triggered when it shouldn't be for CFG and SE rules.

Comments

@marco-carvalho
Copy link

marco-carvalho commented Oct 2, 2024

This code is giving me Change this condition so that it does not always evaluate to 'True'. (S2589) at if (t.Any()):

using System;
using System.Collections.Generic;
using System.Linq;

List<int> t = new();
t.AddRange([]);
if (t.Any()) // Change this condition so that it does not always evaluate to 'True'.[S2589]
{
    Console.WriteLine(1);
}

But when I run it, it doesn't print 1, but Sonar thinks this code should change to not always evaluate to 'True'.

@marco-carvalho marco-carvalho changed the title Fix S2583 FP/FN: Change this condition so that it does not always evaluate to 'True' Fix S2583 FP: Change this condition so that it does not always evaluate to 'True' Oct 2, 2024
@jilles-sg
Copy link

The condition always evaluates to false, so this is not really an FP but an incorrect explanation.

This kind of report is highly dangerous if developers apply it without checking, though.

@marco-carvalho
Copy link
Author

I believe this actually is a false positive. The issue comes from Sonar's static analysis assuming that the if (t.Any()) condition will always evaluate to true. However, since we're adding an empty array to the list with t.AddRange([]), at runtime, the list remains empty, and t.Any() evaluates to false.

So, the runtime behaviour is correct, but Sonar's flagging it as though the condition is always true, which is why I’m classifying this as a false positive. It seems like the static analysis isn’t catching the fact that nothing’s being added to the list.

@marco-carvalho
Copy link
Author

marco-carvalho commented Oct 2, 2024

This also happens if I use a method:

using System;
using System.Collections.Generic;
using System.Linq;

List<int> t = new();
t.AddRange(ReturnsEmpty());
if (t.Any()) // Change this condition so that it does not always evaluate to 'True'.[S2589]
{
    Console.WriteLine(1);
}

List<int> ReturnsEmpty()
{
    return [];
}

@pavel-mikula-sonarsource
Copy link
Contributor

Hi,

Thank you for reporting this, I confirm it is unexpected behavior.

It's hard to tell if it should be called "False Positive" or not, because this S2583 will be replaced with S2583 with a different message, as the condition is always False and the subsequent code is never executed :)

ToDo:

Check if the engine supports [] collection expressions in all scenarios:

  • [] => empty
  • [ 42 ] => non-empty
  • [ ... values ] => propagate (by aggregating non-empty)
  • [ ... a, ... b] => aggregate non-empty
    We need to check this for arrays and lists separately, as the CFG they might differ.

When processing AddRange, take a look at the collection constraint for the argument. When the argument is

  • Known to be empty => Do not modify collection constraint
  • Known to be not-empty => Set non-empty constraint on the collection
  • Be unknown => Remove collection constraint

@pavel-mikula-sonarsource pavel-mikula-sonarsource added Area: CFG/SE CFG and SE related issues. Area: VB.NET VB.NET rules related issues. Area: C# C# rules related issues. Type: CFG/SE FPs Rule IS triggered when it shouldn't be for CFG and SE rules. labels Oct 3, 2024
@pavel-mikula-sonarsource
Copy link
Contributor

pavel-mikula-sonarsource commented Oct 3, 2024

There are going to be FNs in S4158 due to this too. The root cause is #8539

@marco-carvalho
Copy link
Author

This also happens without collection expressions:

using System;
using System.Collections.Generic;
using System.Linq;

List<int> t = new();
t.AddRange(ReturnsEmpty());
if (t.Any()) // Change this condition so that it does not always evaluate to 'True'.[S2589]
{
    Console.WriteLine(1);
}

List<int> ReturnsEmpty()
{
    return new List<int>();
}

@pavel-mikula-sonarsource
Copy link
Contributor

We don't support cross-procedure analysis yet with these rules

@Tim-Pohlmann
Copy link
Contributor

The root cause is not so much the collection expression (though, that might cause some issues as well) but mainly how the engine treats AddRange. See #8570.
This is fixed but not released yet.

@marco-carvalho
Copy link
Author

There is a expected date for a new release? Right now this rule triggers "bug" reports, and we're having to manually ignore new cases like this.

@Tim-Pohlmann
Copy link
Contributor

Unfortunately, there is no expected date for the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: C# C# rules related issues. Area: CFG/SE CFG and SE related issues. Area: VB.NET VB.NET rules related issues. Type: CFG/SE FPs Rule IS triggered when it shouldn't be for CFG and SE rules.
Projects
None yet
Development

No branches or pull requests

4 participants