[clang-tidy] readability-redundant-parentheses false positive on decltype((x)) changes semantics
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
`readability-redundant-parentheses` diagnoses the inner parentheses in `decltype((x))` as redundant and offers a fix-it that removes them. The parentheses are not redundant here: `decltype((x))` is `int&` while `decltype(x)` is `int`, so applying the fix silently changes the program.
Reproducer:
```c++
int main() {
int x = 0;
decltype((x)) ref = x;
ref = 1;
return x != 1;
}
```
```
clang-tidy --checks='-*,readability-redundant-parentheses' test.cpp -- -std=c++17
```
```
test.cpp:3:12: warning: redundant parentheses around expression [readability-redundant-parentheses]
3 | decltype((x)) ref = x;
| ^ ~
```
The unmodified program exits with 0. After applying the fix-it, `ref` becomes a plain `int` copy, the assignment no longer writes through to `x`, and the program exits with 1.
The check already skips the operand of `sizeof`/`alignof`, but a `ParenExpr` that is the operand of a `decltype` specifier is not treated specially. Unlike other contexts, parentheses immediately inside `decltype` are semantically significant (id-expression vs. parenthesized lvalue expression), so the check should never report them regardless of what they wrap.
Reproduced on current main (LLVM 24.0.0git).
Contributor guide
Research direction
Start by reproducing the warning with the readability-redundant-parentheses check and the provided test.cpp command under C++17. Trace how the check handles a ParenExpr inside decltype; done means decltype((x)) is not diagnosed or changed by a fix-it, while the reproducer still exits 0.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100