[tf2][server] Undefined behavior by shifting (1 << 32) introduced in 46b8c3a
First of all, great catch in https://github.com/ValveSoftware/source-sdk-2013/commit/46b8c3a544ef453285b1652c58c201f6f40aa32c @copperpixel, thank you!
Unfortunately, shifting (1 << 32) is undefined behavior (UB), see C++ standard:
(C++11, 5.8p1) "The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand."
On latest MSVC you get (warning C4293: '<<': shift count negative or too big, undefined behavior): https://godbolt.org/z/6vfj8cozj On latest GCC you get (warning: left shift count >= width of type [-Wshift-count-overflow]): https://godbolt.org/z/E791fcM6T
Technically it is better to not rely on UB as compilers behavior may change (undefined means exactly this :)).
Suggest either shift by 31 if 31 bits are enough or promote operand to long long if all 32 bits are used (1U << 32 is still UB):
// Use long long since PLAYER_FLAG_BITS is 32 and (int)1 << 32 is undefined behavior.
long long mask = ( 1LL << PLAYER_FLAG_BITS ) - 1;
long long data = *( int* )pVarData;
pOut->m_Int = static_cast<int>( data & mask );
See https://stackoverflow.com/questions/9860538/unexpected-c-c-bitwise-shift-operators-outcome
Addressed in PR https://github.com/ValveSoftware/source-sdk-2013/pull/876 Thanks for bringing this up!
Function in PR has been dropped in latest sources: https://github.com/ValveSoftware/source-sdk-2013/blob/a62efecf624923d3bacc67b8ee4b7f8a9855abfd/src/game/server/player.cpp