Skip to content

Do not offer the MA0082 code fix when both operands are NaN - #1497

Merged
meziantou merged 1 commit into
mainfrom
feature/ma0082-nan-comparison-fixer-6e8c86
Sep 12, 2026
Merged

meziantou merged 1 commit into
mainfrom
feature/ma0082-nan-comparison-fixer-6e8c86

Conversation

@meziantou

Copy link
Copy Markdown
Owner

Problem

public class Sample
{
    public static object Run() => double.NaN == double.NaN;
}

MA0082 reports both NaN operands. Applying the offered fix produces double.IsNaN(double.NaN), which changes the result of the expression from False to True.

The fixer rewrote x == NaN into IsNaN(x) by picking the other operand of the comparison. When both operands are the NaN sentinel, "the other operand" is itself NaN, so the rewrite loses the IEEE semantics of the comparison. The != form was equally wrong: !double.IsNaN(double.NaN) is false while NaN != NaN is true.

Change

The fixer now returns before registering any action when both operands are recognized NaN constants. The analyzer still reports both operands — the comparison is still worth flagging — but no behavior-changing fix is offered.

I did not add a "replace the whole comparison with the constant result" alternative: MA0082 is a report-only design rule, and folding the expression to false/true is a different transformation than the one the fix advertises.

Notes for the reviewer

The new test sets FixedCode in addition to TestCode. This is needed: Microsoft.CodeAnalysis.Testing skips code fix verification entirely when only TestCode is set, so a test written the usual way passes even while the fix is being applied. I verified the new test actually catches the bug by neutralizing the guard and re-running it — it fails with exactly the reported diff (_ = double.NaN == double.NaN; → _ = double.IsNaN(double.NaN);). Other analyzer tests in this repo likely have the same blind spot.

Validation

  • All 5 DoNotNaNInComparisonsAnalyzerTests pass on every Roslyn version (4.8, 4.14, 5.0, 5.6, 5.9).
  • dotnet run --project src/DocumentationGenerator exits 0 with no markdown changes.

The fixer rewrote `x == NaN` into `IsNaN(x)` by picking the other
operand. When both operands are the NaN sentinel, the other operand is
itself NaN, so `double.NaN == double.NaN` became
`double.IsNaN(double.NaN)`, changing the result from false to true.
The `!=` form was equally wrong: `!double.IsNaN(double.NaN)` is false
while `NaN != NaN` is true.

The analyzer still reports both operands, but no fix is registered when
both of them are recognized NaN constants.

The new test sets FixedCode, as Microsoft.CodeAnalysis.Testing skips the
code fix verification when only TestCode is set.
@meziantou
meziantou merged commit bec4c3f into main Sep 12, 2026
13 checks passed
@meziantou
meziantou deleted the feature/ma0082-nan-comparison-fixer-6e8c86 branch September 12, 2026 04:33
This was referenced Sep 12, 2026
This was referenced Sep 25, 2026
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.

1 participant