summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
authorEllie Hermaszewska <ellieh@nvidia.com>2023-05-05 03:46:42 +0800
committerGitHub <noreply@github.com>2023-05-04 12:46:42 -0700
commitab3ac985479132856613d6dcc8b43f4a4ef8c6b7 (patch)
treee4e911d10b8ec2866e7e408f9a10b51d743ee675 /source/core
parentc0b6f59a6920a9efbb4ecc3b622529db484c64ef (diff)
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 <yonghe@outlook.com>
Diffstat (limited to 'source/core')
-rw-r--r--source/core/slang-common.h31
-rw-r--r--source/core/slang-io.cpp8
2 files changed, 28 insertions, 11 deletions
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 <typename T>
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<typename T> 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<char> 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)