Fix: do not add an offset to a nullptr

This is, by specs, undefined behaviour. See
https://reviews.llvm.org/D67122

In cases where this is done, optimizations done by LLVM can
generate code that causes crashes.

GetVariableAddress() had two (legit) ways this could happen:
- For SaveLoad set to global
- For SaveLoad set to SLE_VAR_NULL, where sld->address is always
  a nullptr, and object could or could not be a nullptr.
This commit is contained in:
Patric Stout 2020-12-04 22:12:39 +01:00 committed by Patric Stout
parent c558936ec3
commit c98717cb45
1 changed files with 12 additions and 1 deletions

View File

@ -873,7 +873,18 @@ static inline bool IsNumericType(VarType conv)
*/
static inline void *GetVariableAddress(const void *object, const SaveLoad *sld)
{
return const_cast<byte *>((const byte*)(sld->global ? nullptr : object) + (ptrdiff_t)sld->address);
/* Entry is a global address. */
if (sld->global) return sld->address;
/* Entry is a null-variable, mostly used to read old savegames etc. */
if (GetVarMemType(sld->conv) == SLE_VAR_NULL) {
assert(sld->address == nullptr);
return nullptr;
}
/* Everything else should be a non-null pointer. */
assert(object != nullptr);
return const_cast<byte *>((const byte *)object + (ptrdiff_t)sld->address);
}
int64 ReadValue(const void *ptr, VarType conv);