If I compile this code
#include <bitset>
int
main(int argc, char** argv) {
std::bitset<96> mask;
mask.set();
return 0;
}
with clang++ -fsanitize=integer test_bitset.cpp
and run the result, I get
.../include/c++/12/bitset:657:46: runtime error: left shift of 18446744073709551615 by 32 places cannot be represented in type 'std::_Sanitize::_WordT' (aka 'unsigned long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior .../include/c++/12/bitset:657:46 in
This looks a little bit like Why does the clang sanitizer think this left shift of an unsigned number is undefined? but if I try to disable the check using
clang++ -fsanitize=integer -fno-sanitize=unsigned-integer-overflow test_bitset.cpp
the undefined behavior persists. To add to the confusion, if I enable "all" integer checks manually (as mentioned in the docs)
clang++ -fsanitize=signed-integer-overflow,unsigned-integer-overflow,shift,integer-divide-by-zero,implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change test_bitset.cpp
the undefined behavior is gone. So apparently -fsanitize=integer does more than that?
I can silence the error using a blacklist on bitset but I really want to know whether it is a bug in the stdlib or can be ignored safely.
I tried this with clang 14 and clang 15 on a standard ubuntu 22.04. Any hints are appreciated.
As @user17732522 pointed out correctly it is just a bug in the clang docs. The correct call to avoid the check is
clang++ -fsanitize=integer -fno-sanitize=unsigned-shift-base test_bitset.cppand the check is just oversensitive it is not an undefined behavior.