diff --git a/irr/include/irrTypes.h b/irr/include/irrTypes.h index 6c0ee661c..910991689 100644 --- a/irr/include/irrTypes.h +++ b/irr/include/irrTypes.h @@ -85,6 +85,22 @@ typedef char fschar_t; /** prefer to use the override keyword for new code */ #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 +#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 /** some compilers can create those by directly writing the code like 'code', but some generate warnings so we use this macro here */ diff --git a/irr/include/vector2d.h b/irr/include/vector2d.h index 182965295..63be1f246 100644 --- a/irr/include/vector2d.h +++ b/irr/include/vector2d.h @@ -131,16 +131,20 @@ public: T &operator[](u32 index) { - _IRR_DEBUG_BREAK_IF(index > 1) // access violation - - return *(&X + index); + switch (index) { + case 0: return X; + case 1: return Y; + default: IRR_CODE_UNREACHABLE(); + } } const T &operator[](u32 index) const { - _IRR_DEBUG_BREAK_IF(index > 1) // access violation - - return *(&X + index); + switch (index) { + case 0: return X; + case 1: return Y; + default: IRR_CODE_UNREACHABLE(); + } } //! sort in order X, Y. diff --git a/irr/include/vector3d.h b/irr/include/vector3d.h index 9bacf977e..780686c7a 100644 --- a/irr/include/vector3d.h +++ b/irr/include/vector3d.h @@ -117,16 +117,22 @@ public: T &operator[](u32 index) { - _IRR_DEBUG_BREAK_IF(index > 2) // access violation - - return *(&X + index); + switch (index) { + case 0: return X; + case 1: return Y; + case 2: return Z; + default: IRR_CODE_UNREACHABLE(); + } } const T &operator[](u32 index) const { - _IRR_DEBUG_BREAK_IF(index > 2) // access violation - - return *(&X + index); + switch (index) { + case 0: return X; + case 1: return Y; + case 2: return Z; + default: IRR_CODE_UNREACHABLE(); + } } //! sort in order X, Y, Z. diff --git a/irr/src/OpenGL/Driver.cpp b/irr/src/OpenGL/Driver.cpp index 0057611d4..6e30063aa 100644 --- a/irr/src/OpenGL/Driver.cpp +++ b/irr/src/OpenGL/Driver.cpp @@ -104,8 +104,7 @@ static const VertexType &getVertexTypeDescription(E_VERTEX_TYPE type) case EVT_TANGENTS: return vtTangents; default: - assert(false); - CODE_UNREACHABLE(); + IRR_CODE_UNREACHABLE(); } } diff --git a/irr/src/os.h b/irr/src/os.h index bcc096f95..238b71653 100644 --- a/irr/src/os.h +++ b/irr/src/os.h @@ -10,22 +10,6 @@ #include "ILogger.h" #include "ITimer.h" -// CODE_UNREACHABLE(): Invokes undefined behavior for unreachable code optimization -#if defined(__cpp_lib_unreachable) -#include -#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 {