From ab3ac985479132856613d6dcc8b43f4a4ef8c6b7 Mon Sep 17 00:00:00 2001 From: Ellie Hermaszewska Date: Fri, 5 May 2023 03:46:42 +0800 Subject: Add SLANG_ASSUME and use it in release asserts (#2859) * Remove UNREACHABLE * formatting * Remove unused SLANG_EXPECT macros * Add SLANG_ASSUME and use it in release asserts * Reassure GCC that we are using memcpy responsibly --------- Co-authored-by: Yong He --- source/core/slang-common.h | 31 +++++++++++++++++++++++-------- source/core/slang-io.cpp | 8 +++++--- 2 files changed, 28 insertions(+), 11 deletions(-) (limited to 'source/core') diff --git a/source/core/slang-common.h b/source/core/slang-common.h index cd1490a20..5cf0432f2 100644 --- a/source/core/slang-common.h +++ b/source/core/slang-common.h @@ -76,28 +76,43 @@ namespace Slang template SLANG_FORCE_INLINE T* clone(IClonable* clonable) { return (T*)clonable->clone(T::getTypeGuid()); } +} // TODO: Shouldn't these be SLANG_ prefixed? #ifdef _MSC_VER #define UNREACHABLE_RETURN(x) -#define UNREACHABLE(x) #else #define UNREACHABLE_RETURN(x) return x; -#define UNREACHABLE(x) x; #endif -} +// +// Use `SLANG_ASSUME(myBoolExpression);` to inform the compiler that the condition is true. +// Do not rely on side effects of the condition being performed. +// +#if defined(__cpp_assume) +# define SLANG_ASSUME(X) [[assume(X)]] +#elif SLANG_GCC +# define SLANG_ASSUME(X) do{if(!(X)) __builtin_unreachable();} while(0) +#elif SLANG_CLANG +# define SLANG_ASSUME(X) __builtin_assume(X) +#elif SLANG_VC +# define SLANG_ASSUME(X) __assume(X) +#else + [[noreturn]] inline void invokeUndefinedBehaviour() {} +# define SLANG_ASSUME(X) do{if(!(X)) invokeUndefinedBehaviour();} while(0) +#endif +// +// Assertions abort in debug builds, but inform the compiler of true +// assumptions in release builds +// #ifdef _DEBUG -#define SLANG_EXPECT(VALUE, MSG) if(VALUE) {} else SLANG_ASSERT_FAILURE(MSG) -#define SLANG_ASSERT(VALUE) SLANG_EXPECT(VALUE, #VALUE) +#define SLANG_ASSERT(VALUE) do{if(!(VALUE)) SLANG_ASSERT_FAILURE(#VALUE);} while(0) #else -#define SLANG_EXPECT(VALUE, MSG) do {} while(0) -#define SLANG_ASSERT(VALUE) do {} while(0) +#define SLANG_ASSERT(VALUE) SLANG_ASSUME(VALUE) #endif #define SLANG_RELEASE_ASSERT(VALUE) if(VALUE) {} else SLANG_ASSERT_FAILURE(#VALUE) -#define SLANG_RELEASE_EXPECT(VALUE, WHAT) if(VALUE) {} else SLANG_UNEXPECTED(WHAT) template void slang_use_obj(T&) {} diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp index 81f0cbf87..8a2243b15 100644 --- a/source/core/slang-io.cpp +++ b/source/core/slang-io.cpp @@ -124,9 +124,11 @@ namespace Slang builder << "/tmp/" << inPrefix << "-XXXXXX"; List buffer; - buffer.setCount(builder.getLength() + 1); - ::memcpy(buffer.getBuffer(), builder.getBuffer(), builder.getLength()); - buffer[builder.getLength()] = 0; + auto copySize = builder.getLength(); + buffer.setCount(copySize + 1); + SLANG_ASSERT(copySize < PTRDIFF_MAX); // Shhh gcc, it's ok, we're not copying 9000 Petabytes + ::memcpy(buffer.getBuffer(), builder.getBuffer(), copySize); + buffer[copySize] = 0; int handle = mkstemp(buffer.getBuffer()); if (handle == -1) -- cgit v1.2.3