mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Fix operator[] for vector2d and vector3d being potentially UB (#15977)
We don't have a C++ expert on hand, but taking a pointer to one member and expecting to access another by an offset is very fishy: - for one, there could theoretically be padding - the compiler might assume that we are only writing to that first member The new code has shown to be free for constant parameter values. Non-constant ones cause the assembly to have branches (why?), but we don't use that much.
This commit is contained in:
parent
46db688cc8
commit
a00b9cab36
5 changed files with 39 additions and 30 deletions
|
@ -85,6 +85,22 @@ typedef char fschar_t;
|
||||||
/** prefer to use the override keyword for new code */
|
/** prefer to use the override keyword for new code */
|
||||||
#define _IRR_OVERRIDE_ override
|
#define _IRR_OVERRIDE_ override
|
||||||
|
|
||||||
|
// Invokes undefined behavior for unreachable code optimization
|
||||||
|
// Note: an assert(false) is included first to catch this in debug builds
|
||||||
|
#if defined(__cpp_lib_unreachable)
|
||||||
|
#include <utility>
|
||||||
|
#define IRR_CODE_UNREACHABLE() do { _IRR_DEBUG_BREAK_IF(1) std::unreachable(); } while(0)
|
||||||
|
#elif defined(__has_builtin)
|
||||||
|
#if __has_builtin(__builtin_unreachable)
|
||||||
|
#define IRR_CODE_UNREACHABLE() do { _IRR_DEBUG_BREAK_IF(1) __builtin_unreachable(); } while(0)
|
||||||
|
#endif
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define IRR_CODE_UNREACHABLE() do { _IRR_DEBUG_BREAK_IF(1) __assume(false); } while(0)
|
||||||
|
#endif
|
||||||
|
#ifndef IRR_CODE_UNREACHABLE
|
||||||
|
#define IRR_CODE_UNREACHABLE() (void)0
|
||||||
|
#endif
|
||||||
|
|
||||||
//! creates four CC codes used in Irrlicht for simple ids
|
//! creates four CC codes used in Irrlicht for simple ids
|
||||||
/** some compilers can create those by directly writing the
|
/** some compilers can create those by directly writing the
|
||||||
code like 'code', but some generate warnings so we use this macro here */
|
code like 'code', but some generate warnings so we use this macro here */
|
||||||
|
|
|
@ -131,16 +131,20 @@ public:
|
||||||
|
|
||||||
T &operator[](u32 index)
|
T &operator[](u32 index)
|
||||||
{
|
{
|
||||||
_IRR_DEBUG_BREAK_IF(index > 1) // access violation
|
switch (index) {
|
||||||
|
case 0: return X;
|
||||||
return *(&X + index);
|
case 1: return Y;
|
||||||
|
default: IRR_CODE_UNREACHABLE();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const T &operator[](u32 index) const
|
const T &operator[](u32 index) const
|
||||||
{
|
{
|
||||||
_IRR_DEBUG_BREAK_IF(index > 1) // access violation
|
switch (index) {
|
||||||
|
case 0: return X;
|
||||||
return *(&X + index);
|
case 1: return Y;
|
||||||
|
default: IRR_CODE_UNREACHABLE();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! sort in order X, Y.
|
//! sort in order X, Y.
|
||||||
|
|
|
@ -117,16 +117,22 @@ public:
|
||||||
|
|
||||||
T &operator[](u32 index)
|
T &operator[](u32 index)
|
||||||
{
|
{
|
||||||
_IRR_DEBUG_BREAK_IF(index > 2) // access violation
|
switch (index) {
|
||||||
|
case 0: return X;
|
||||||
return *(&X + index);
|
case 1: return Y;
|
||||||
|
case 2: return Z;
|
||||||
|
default: IRR_CODE_UNREACHABLE();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const T &operator[](u32 index) const
|
const T &operator[](u32 index) const
|
||||||
{
|
{
|
||||||
_IRR_DEBUG_BREAK_IF(index > 2) // access violation
|
switch (index) {
|
||||||
|
case 0: return X;
|
||||||
return *(&X + index);
|
case 1: return Y;
|
||||||
|
case 2: return Z;
|
||||||
|
default: IRR_CODE_UNREACHABLE();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! sort in order X, Y, Z.
|
//! sort in order X, Y, Z.
|
||||||
|
|
|
@ -104,8 +104,7 @@ static const VertexType &getVertexTypeDescription(E_VERTEX_TYPE type)
|
||||||
case EVT_TANGENTS:
|
case EVT_TANGENTS:
|
||||||
return vtTangents;
|
return vtTangents;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
IRR_CODE_UNREACHABLE();
|
||||||
CODE_UNREACHABLE();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
irr/src/os.h
16
irr/src/os.h
|
@ -10,22 +10,6 @@
|
||||||
#include "ILogger.h"
|
#include "ILogger.h"
|
||||||
#include "ITimer.h"
|
#include "ITimer.h"
|
||||||
|
|
||||||
// CODE_UNREACHABLE(): Invokes undefined behavior for unreachable code optimization
|
|
||||||
#if defined(__cpp_lib_unreachable)
|
|
||||||
#include <utility>
|
|
||||||
#define CODE_UNREACHABLE() std::unreachable()
|
|
||||||
#elif defined(__has_builtin)
|
|
||||||
#if __has_builtin(__builtin_unreachable)
|
|
||||||
#define CODE_UNREACHABLE() __builtin_unreachable()
|
|
||||||
#endif
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#define CODE_UNREACHABLE() __assume(false)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CODE_UNREACHABLE
|
|
||||||
#define CODE_UNREACHABLE() (void)0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue