Browse Source

Disable some signed shift UBSAN warnings

On Clang we can do this globally via a sanitizer blacklist, but that's not supported on GCC (yet):
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61978

We disable these warnings because all compilers implement them in the
same way according to the N2218 proposal to standardize the behaviour:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2218.htm
pull/353/head
Gleb Mazovetskiy 7 years ago committed by Anders Jenbo
parent
commit
fb37bbf675
  1. 12
      Source/player.cpp
  2. 3
      Source/render.cpp
  3. 22
      Source/sha.cpp

12
Source/player.cpp

@ -1293,6 +1293,9 @@ void StartWalk(int pnum, int xvel, int yvel, int xadd, int yadd, int EndDir, int
}
}
#if defined(__clang__) || defined(__GNUC__)
__attribute__((no_sanitize("shift-base")))
#endif
void StartWalk2(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int EndDir, int sdir)
{
int px, py;
@ -1372,6 +1375,9 @@ void StartWalk2(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int
}
}
#if defined(__clang__) || defined(__GNUC__)
__attribute__((no_sanitize("shift-base")))
#endif
void StartWalk3(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int mapx, int mapy, int EndDir, int sdir)
{
int px, py, x, y;
@ -1678,6 +1684,9 @@ void RespawnDeadItem(ItemStruct *itm, int x, int y)
itm->_itype = ITYPE_NONE;
}
#if defined(__clang__) || defined(__GNUC__)
__attribute__((no_sanitize("shift-base")))
#endif
void StartPlayerKill(int pnum, int earflag)
{
BOOL diablolevel;
@ -2019,6 +2028,9 @@ void InitLevelChange(int pnum)
}
}
#if defined(__clang__) || defined(__GNUC__)
__attribute__((no_sanitize("shift-base")))
#endif
void StartNewLvl(int pnum, int fom, int lvl)
{
InitLevelChange(pnum);

3
Source/render.cpp

@ -163,6 +163,9 @@ inline static void RenderLine(BYTE **dst, BYTE **src, int n, BYTE *tbl, DWORD ma
}
}
#if defined(__clang__) || defined(__GNUC__)
__attribute__((no_sanitize("shift-base")))
#endif
void RenderTile(BYTE *pBuff)
{
int i, j;

22
Source/sha.cpp

@ -4,29 +4,19 @@
DEVILUTION_BEGIN_NAMESPACE
// Diablo's "SHA1" is different from actual SHA1 in that it uses arithmetic
// NOTE: Diablo's "SHA1" is different from actual SHA1 in that it uses arithmetic
// right shifts (sign bit extension).
//
// Note that:
// 1. Tere is a C++20 proposal to make right shift always defined
// as an arithmetic shift with sign extension:
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0907r1.html
// 2. Modern C++ compilers (GCC 8+, Clang 7+) compile the portable code
// to the same assembly as the implementation defined `value >> bits`:
// https://stackoverflow.com/a/53766752
namespace {
std::uint32_t asr(std::int32_t value, std::int32_t amount)
{
return value < 0 ? ~(~value >> amount) : value >> amount;
}
/*
* Diablo-"SHA1" circular left shift.
*/
std::uint32_t SHA1CircularShift(std::uint32_t bits, std::uint32_t word) {
return (word << bits) | asr(word, 32 - bits);
#if defined(__clang__) || defined(__GNUC__)
__attribute__((no_sanitize("shift-base")))
#endif
std::uint32_t SHA1CircularShift(std::uint32_t bits, std::int32_t word) {
return (word << bits) | (word >> (32 - bits));
}
} // namespace

Loading…
Cancel
Save