github / github/codeql

C#: cs/simplifiable-boolean-expression false positive on Nullable<bool> compared with a literal

Open Beginner friendly
#22,556 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
CodeQL
Stars
10.1k
Forks
2.1k
Avg merge
2d 15h
Merged PRs (30d)
141

Description

**Description of the false positive**

`cs/simplifiable-boolean-expression` flags `x == false` and `x == true` when `x` is a `bool?` (`Nullable`), suggesting `!x` / `x`. The suggestion is not equivalent and does not compile: `!x` on a `bool?` is `CS0266`/`CS0023`, and using a `bool?` directly as a condition is `CS0266`. Comparing a nullable bool with a literal is the idiomatic way to write "has a value and it is false", and it is also the form EF Core translates cleanly (`x is false` is not allowed in an expression tree, and `x.HasValue && !x.Value` is what the rule is meant to steer people away from).

`simplifyBinaryExpr` in `SimplifyBoolExpr.ql` only matches on the operator; it never checks the operand's type. Restricting the `==`/`!=`-with-literal cases to operands whose type is `bool` (not `Nullable`) would remove the false positive.

The alert is raised as a Code Quality finding on every PR touching one of these comparisons, and there is no way to filter a rule under Code Quality's default setup, so it recurs.

**Code samples or links to source code**

```csharp
public class Rule
{
public bool? ScanToLocation { get; set; }
public int? LocationId { get; set; }
}

// Flagged: "The expression 'A == false' can be simplified to '!A'."
// !r.ScanToLocation does not compile for a bool?.
var rules = context.Rules
.Where(r => r.ScanToLocation == false && r.LocationId != null)
.ToList();

// Also flagged, same problem
var off = rules.Where(r => r.ScanToLocation == false);
```

Expected: no alert when the operand is `Nullable`.

**URL to the alert on GitHub code scanning (optional)**

Private repository (Code Quality PR comments, CodeQL CLI 2.27.0 with the `code-quality` suite).

Contributor guide

Open the contributing guide

Research direction

Start with simplifyBinaryExpr in SimplifyBoolExpr.ql, then inspect how the == and != literal cases determine operand types. Use the nullable-bool examples in the issue to verify that comparisons no longer produce an alert while the existing simplification behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
devtools
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.