Following the example on https://en.cppreference.com/w/cpp/types/type_index and compiling with -fsanitize=address,integer,undefined
reveals an undefined behaviour. Code is:
struct A
{
virtual ~A()
{}
};
struct B : A
{
};
struct C : A
{
};
int main() {
std::unordered_map<std::type_index, std::string> type_names;
std::cout << "A" << std::endl;
type_names[std::type_index(typeid(int))] = "int";
std::cout << "B" << std::endl;
type_names[std::type_index(typeid(double))] = "double";
std::cout << "C" << std::endl;
type_names[std::type_index(typeid(A))] = "A";
std::cout << "D" << std::endl;
type_names[std::type_index(typeid(B))] = "B";
std::cout << "E" << std::endl;
type_names[std::type_index(typeid(C))] = "C";
std::cout << "F" << std::endl;
return 0;
}
which after compiled and ran yields:
A
B
C
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/typeinfo:192:26: runtime error: unsigned integer overflow: 8244747390267580164 * 33 cannot be represented in type 'unsigned long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/typeinfo:192:26 in
D
E
F
As seen, clang complains about undefined behaviour user defined types. Does anybody know what a correct implementation that does not cause undefined behaviour looks like?
Unsigned integer overflow is not undefined behaviour, however UBSan still has an option to check for it because it is often still a bug. But not in this case. This warning is provoked by a totally innocent hash function. It is supposed to have unsigned integer overflows.
You can silence this warning.
You can also report a bug to libc++ maintainers. They probably should add
or some such to the offending functions.