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

Update S4070 to accept negative numbers #8211

Merged
merged 2 commits into from
Oct 18, 2023
Merged

Conversation

costin-zaharia-sonarsource
Copy link
Member

if their absolute value is a power of two.

Fixes #7991

@costin-zaharia-sonarsource costin-zaharia-sonarsource force-pushed the costin/7991 branch 2 times, most recently from 28c8b1d to 667ca84 Compare October 17, 2023 12:51
@costin-zaharia-sonarsource
Copy link
Member Author

@antonioaversa, @sebastien-marichal what do you think?

From the runtime point of view, the negative values are also acceptable if their absolute value is a power of 2. From the usage point of view, the math can get confusing but that looks to me as a separate dedicated rule.

From the docs:

Use caution if you define a negative number as a flag enumerated constant because many flag positions might be set to 1, which might make your code confusing and encourage coding errors.

Copy link
Contributor

@sebastien-marichal sebastien-marichal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!
I left one educational question.

: null;

private static bool IsValidFlagValue(ulong? enumValue, List<ulong> allValues) =>
private static bool IsValidFlagValue(BigInteger? enumValue, IEnumerable<BigInteger> allValues) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Educational: Why did you change the type from List to IEnumerable?
Isn't there a risk of multiple enumeration if we drop the ToList on allValues line 58?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the method should not be aware of how it is used. If it does the iteration only once and doesn't use API specific to the collection it should use the most generic type. This in some scenarios will allow lazy evaluation, or no evaluation at all if the path is not reached.

Copy link
Contributor

@antonioaversa antonioaversa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, we should be able to use BigInteger.Abs.

Comment on lines 94 to 96
|| (value.Sign == -1
? BigInteger.Multiply(value, -1).IsPowerOfTwo
: value.IsPowerOfTwo);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BigInteger.Abs(value).IsPowerOfTwo

Suggested change
|| (value.Sign == -1
? BigInteger.Multiply(value, -1).IsPowerOfTwo
: value.IsPowerOfTwo);
|| BigInteger.Abs(value).IsPowerOfTwo

@antonioaversa
Copy link
Contributor

@costin-zaharia-sonarsource The safeguard and the _ => null seem difficult to cover.
I wonder whether we could just remove the safeguard, and return null whenever the type doesn't match one of the 8 types above.
I also wonder when enumMember.HasConstantValue is false and whether we can write an incomplete tuple to cover also tuple => tuple.Member.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax().GetLocation().

if their absolute value is a power of two.
@costin-zaharia-sonarsource
Copy link
Member Author

@antonioaversa I removed the safeguard. Regarding the tuple, I think that's a scenario that could not actually happen, to have an enum declaration with a member that doesn't have a location. It looks like defensive coding.

@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

95.2% 95.2% Coverage
0.0% 0.0% Duplication

@costin-zaharia-sonarsource costin-zaharia-sonarsource marked this pull request as ready for review October 18, 2023 11:30
@costin-zaharia-sonarsource costin-zaharia-sonarsource merged commit 35028aa into master Oct 18, 2023
@costin-zaharia-sonarsource costin-zaharia-sonarsource deleted the costin/7991 branch October 18, 2023 11:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix S4070 FP: Raised on flagged enum
3 participants