SonarSource / sonar-dotnet

Code analyzer for C# and VB.NET projects
https://redirect.sonarsource.com/plugins/csharp.html
GNU Lesser General Public License v3.0
770 stars 226 forks source link

New rule for checking an enum flag is set verifies enum value #1500

Open alexangas opened 6 years ago

alexangas commented 6 years ago

Description

Where an attempt is made to check if an enum value has a flag set, then SonarC# should verify that this can be done correctly.

This issue suggests a new rule to cover this, based off these remarks in MS API documentation.

Repro steps

Given one of the following code patterns is used to check if a flag is set:

enumValue.HasFlag(Colors.SomeValue);
(enumValue & Colors.SomeValue) == Colors.SomeValue;

Then this rule would be triggered if the target enum declaration does not have the FlagsAttribute, or if one of the values in the enum declaration is zero or not a power of two.

Related example problematic enum declaration:

// [Flags] // (missing FlagsAttribute)
public enum Colors
{
    None = 0, // Value of 0
    Red = 1,
    Orange = 2,
    Yellow = 3 // Value is not a power of 2
}

Related information

Corniel commented 5 years ago

I was thinking of this as well. There are according to me, 3 scenario's that are none-compliant, if you use Enum.HasFlag(Enum):

Like this code:

public class HasFlag
{
    [Flags]
    public enum Flagged
    {
        None = 0,
        UnionJack = 1,
        StarSpangledBanner = 2,
    }

    public void Test(Flagged flags, LoaderOptimization optimization)
    {
        var noFlag = optimization.HasFlag(LoaderOptimization.MultiDomain); // none-compliant. LoaderOptimization is not a flags enum.
        var hasNone = flags.HasFlag(Flagged.None); //none-compliant, None is not a flag value.
        var hasOther = flags.HasFlag(LoaderOptimization.SingleDomain); // not-compliant, enum types don't match
        var hasUS = flags.HasFlag(Flagged.StarSpangledBanner); // compliant
    }
}