llvm / llvm/llvm-project

[clang-tidy] Add `suspicious-nolint` check

Open
#184,034 7 comments 0 reactions 0 assignees View on GitHub
check-request clang-tidy
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Following the discussion here: https://discourse.llvm.org/t/rfc-add-non-blocking-precommit-clang-tidy-analysis, one of the concerns about enabling clang-tidy in pre-commit was that `NOLINT` comments “get out of sync with reality too easily”. This check aims to solve that problem. Even if the RFC above is not accepted, such a check should still be useful to a wider community.

There was an older patch that tried to do something similar: https://reviews.llvm.org/D41326, but it was never accepted. This new check would probably fit best into the `bugprone` or `misc` module.

## What the check should do

### 1. Forbid non-targeted `NOLINT` comments

It should be possible to forbid “catch-all” `NOLINT`s such as:

```cpp
// NOLINT
// NOLINT(*)
```

and the same for `NOLINTNEXTLINE` and `NOLINTBEGIN`/`NOLINTEND`.

The idea is to force targeted suppressions and avoid silently hiding new diagnostics that appear on already `NOLINT`ed lines.

**Fix-it idea:**
If there are diagnostics on that line, the check should suggest adding their check names into the `NOLINT` list. If there are several diagnostics, it should suggest a list of names.

#### 1.1. Optionally forbid wildcard patterns

With a separate option, it should be possible to reject patterns like:

```cpp
// NOLINT(google-*)
```

While this is more targeted than `NOLINT(*)`, it can still hide many issues at once.

### 2. Require an explaining comment

The check should be able to enforce that every `NOLINT` has an explanation, for example:

```cpp
// NOLINT: reason
// NOLINT(xxx): reason
```

Once `NOLINT` is parsed, there should be some non-whitespace text after it.

Open question to the community:
Should the separator format be enforced (e.g. `// NOLINT(xxx): reason`), configurable, or is “any non-whitespace text after the `NOLINT`” good enough?

This is a purely stylistic rule, but some teams want it so they don’t have to ask “why is this `NOLINT` here?” every time.

### 3. Check that `NOLINT` actually suppresses something

If a `NOLINT` does not match any diagnostic on the line, it should be reported.

Rules for matching:

- Non-targeted `NOLINT` (no checks listed):
It should match any diagnostic on that line.
- Patterned `NOLINT` (e.g. `NOLINT(google-*)`):
It should match at least one diagnostic whose check name fits the pattern.
- `NOLINT` with a list of checks/patterns:
Each element in the list should be checked separately.

**Fix-it idea:**

- If none of the listed checks/patterns match anything, suggest removing the whole `NOLINT` comment.
- If only some elements are unused, suggest removing just those elements from the list.

### 4. Warn on unknown check names

If a `NOLINT` refers to a check name that clang-tidy does not know about, the check should warn.

This is useful when updating clang-tidy: a check may have been removed or renamed, but the old name may still linger in the code.

---

Because `NOLINT` comments are also used by other tools (for example `cpplint`), and because of the concerns raised in the older review, it should be possible to enable/disable parts of this check ((1), (3), (4)) based on patterns, and for both checks known and unknown to clang-tidy.

Contributor guide

Open the contributing guide

Research direction

Start by reading clang-tidy's existing NOLINT parsing and diagnostic-suppression behavior, then review the linked RFC and older patch D41326. Define how non-targeted, wildcard, explanatory, unused, and unknown-check cases should be handled, including configurable patterns and fix-its. Done means the agreed behaviors are implemented with coverage for each NOLINT form and matching rule.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.