clang-tidy misc-confusable-identifiers check does not diagnose confusability due to normalization
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
[Testcase](https://godbolt.org/z/4Kzna9qo6):
```c++
int ü = 1;
int ü = 2;
int fool = 1;
int foo1 = 2;
```
GCC has an enabled-by-default warning for the first case. You probably can't see what's happening here: in the first line, the variable name is in NFC (a single code point: u with diaresis), whereas in the second line the variable name is in NFD (two code points: u and a combining diaresis). These are distinct identifiers, so that's not a redeclaration of the first identifier. Neither clang nor clang-tidy has any check for this.
clang-tidy's `misc-confusable-identifiers` check does catch the second case. Depending on your font, that one might be more obvious: the first declaration ends in an L, whereas the second ends in a 1. `misc-confusable-identifiers` should catch the first case too; I'm surprised it's not already caught there, given that [the skeleton algorithm](https://www.unicode.org/reports/tr39/tr39-3.html#Confusable_Detection) for confusable detection starts by converting the identifiers to NFD, so both identifiers should map to the same skeleton and hence trigger the warning.
Contributor guide
Research direction
Reproduce the linked Compiler Explorer testcase and inspect the implementation and tests for clang-tidy's misc-confusable-identifiers check. Compare how the NFC and NFD identifiers are normalized before skeleton generation. Done means the check diagnoses the two visually equivalent identifiers while preserving the existing fool/foo1 behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100