In C++17 the initialization rules for enum classes are relaxed compared their initialization prior C++17.
Before C++17 the list-initialization of enum classes required and explicit mention of the type.
For enum classes there is no implicit conversion from the underlying type to the enum class, so an explicit cast or the equivalent must be used:
std::byte a = std::byte(0xFF);
std::byte b = static_cast<std::byte>(0xFF);
C++17 relaxed this by allowing to omit the name of the type by using direct list initialization:
std::byte postcpp17 {0xFF};
See: https://en.cppreference.com/w/cpp/language/enum#enum_relaxed_init_cpp17
EnumCastOutOfRangeChecker now correctly recognizes this, and no longer gives false positive reports.
Details
- Reviewers
Szelethus
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
I have chosen to use std::byte to demonstrate enum class behaviour, as the original false positive the led to the creation of this patch also used C++17 feature std::byte.
Just the test cases are added so far.
In C++17 the initialization rules for enum classes are relaxed.
In what way are they relaxed compared to regular enums?
Anyway, IMO those are indeed FPs, see https://godbolt.org/z/7z984bz6v
I'm looking forward to the fix. Thanks.
The initialization rules are relaxed compared to their pre-C++17 state, so now there is a possibility of an initialization for enum classes without explicitly mentioning the underlying type.
I have updated the revision body.
That all being said, there is another fundamental issue with this checker, namely that the possible value range is I think restricted to the ones explicitly mentioned in the enumerators.
For example in the std::byte case even the old way of initializing gives a false positive.
I am investigating the issue, and have found so far, that fixed underlying-typed and non-fixed underlying-typed enums behave differently, which is not considered in the checker code.
Relevant info dump for future quoting:
https://eel.is/c++draft/dcl.enum#5
https://eel.is/c++draft/dcl.enum#7
https://eel.is/c++draft/dcl.enum#8
https://eel.is/c++draft/expr.static.cast#10
https://eel.is/c++draft/conv.fpint