| Issue |
178745
|
| Summary |
[clang-tidy] New check: readability-misleading-const-variant
|
| Labels |
clang-tidy
|
| Assignees |
|
| Reporter |
denzor200
|
## Motivation
The C++ standard allows `std::variant` to contain `const`-qualified types, but this can lead to confusion during code review and maintenance. When a variant contains a `const` alternative, assignments like `v = value;` appear to modify a `const` object, which contradicts programmer intuition about `const` semantics. While technically correct (the entire variant object is replaced), this pattern violates the principle of least astonishment and can lead to misinterpretation.
## Detection Pattern
The check should warn when:
1. A `std::variant` (or `std::variant`-like type) contains at least one `const`-qualified alternative type
2. An assignment operation (`operator=`) is performed on such a variant
3. The assignment would cause the active alternative to change from a `const` type to a different type
## Example
```cpp
// Triggers warning:
std::variant<const int, unsigned> v{0};
v = 0u; // Warning: replacing const alternative in std::variant
std::variant<const int> v2{0};
// v2 = 5; // CE - so, out of scope for this check
// Does not trigger (no const alternatives):
std::variant<int, unsigned> v3{0};
v3 = 0u; // OK
```
## Suggested Fixes
The check should suggest one or more of the following alternatives:
1. **Use `emplace` for explicit type replacement:**
```cpp
// Before:
v = 0u;
// After:
v.emplace<unsigned>(0u);
```
2. **Remove `const` qualification if not semantically required:**
```cpp
// Before:
std::variant<const int, unsigned> v{0};
// After:
std::variant<int, unsigned> v{0};
```
3. **Use a named wrapper for clarity:**
```cpp
// Before:
std::variant<const int, unsigned> v{0};
// After:
struct ConstInt { const int value; };
std::variant<ConstInt, unsigned> v{ConstInt{0}};
```
## Implementation Considerations
- Should detect both direct `std::variant` usage and type aliases
- Should consider common variant-like implementations (e.g., `boost::variant`)
- Should handle nested variants and template instantiations
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs