NET-1997 New rule for checking an enum flag is set verifies enum value
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
- SonarC# Version: 7.2
- Visual Studio Version: N/A
- If running through the Scanner for MSBuild, its version: N/A
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):
- Enum type used, is not decorated with the
FlagsAttribute - Enum types don't match
- the value to test the flag for, represents the 0 value
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
}
}
Internal ticket NET-1997