From 91b348912ba1da524f8230647c514acdcfb9f3c7 Mon Sep 17 00:00:00 2001 From: Antonio Maiorano Date: Thu, 1 Aug 2024 15:37:02 -0400 Subject: [PATCH] Add llvm assertions trap and no strings (#6838) Add option LLVM_ASSERTIONS_NO_STRINGS When defined, drop the stringized expression, __FILE__, and __FUNCTION__ strings passed to llvm_assert. This dramatically reduces the binary size, which is useful when enabling assertions in a non-debug build. Add option LLVM_ASSERTIONS_TRAP When enabled, this forces asserts to always trap. Currently, on Windows asserts calls RaiseException, while they trap on non-Windows. This option makes the assertion behaviour consistent across platforms. --- CMakeLists.txt | 3 +++ cmake/modules/HandleLLVMOptions.cmake | 7 +++++++ include/llvm/llvm_assert/assert.h | 7 +++++++ lib/Support/assert.cpp | 26 +++++++++++++++++--------- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e721504f8..8f7db99784 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -325,6 +325,9 @@ else() option(LLVM_ENABLE_ASSERTIONS "Enable assertions" ON) endif() +option(LLVM_ASSERTIONS_TRAP "Force assertions to always trap, rather than the default unspecified behavior (e.g. RaiseException on Windows)" OFF) +option(LLVM_ASSERTIONS_NO_STRINGS "Make assertion macro drops strings to reduce binary size" OFF) + set(LLVM_ABI_BREAKING_CHECKS "WITH_ASSERTS" CACHE STRING "Enable abi-breaking checks. Can be WITH_ASSERTS, FORCE_ON or FORCE_OFF.") diff --git a/cmake/modules/HandleLLVMOptions.cmake b/cmake/modules/HandleLLVMOptions.cmake index 7b8edecd3f..19e02121b5 100644 --- a/cmake/modules/HandleLLVMOptions.cmake +++ b/cmake/modules/HandleLLVMOptions.cmake @@ -78,6 +78,13 @@ if( LLVM_ENABLE_ASSERTIONS ) "${flags_var_to_scrub}" "${${flags_var_to_scrub}}") endforeach() endif() + + if (LLVM_ASSERTIONS_TRAP) + add_definitions( -DLLVM_ASSERTIONS_TRAP ) + endif() + if (LLVM_ASSERTIONS_NO_STRINGS) + add_definitions( -DLLVM_ASSERTIONS_NO_STRINGS ) + endif() else() # Disable assertions in Debug builds if( uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" ) diff --git a/include/llvm/llvm_assert/assert.h b/include/llvm/llvm_assert/assert.h index ac4173affe..7a66227dfc 100644 --- a/include/llvm/llvm_assert/assert.h +++ b/include/llvm/llvm_assert/assert.h @@ -37,8 +37,15 @@ void llvm_assert(const char *Message, const char *File, unsigned Line, } #endif +// If LLVM_ASSERTIONS_NO_STRINGS is defined, pass empty strings to llvm_assert +// to reduce binary size. +#ifdef LLVM_ASSERTIONS_NO_STRINGS +#define assert(Expression) \ + ((void)((!!(Expression)) || (llvm_assert("", "", 0, ""), 0))) +#else #define assert(Expression) \ ((void)((!!(Expression)) || \ (llvm_assert(#Expression, __FILE__, __LINE__, __FUNCTION__), 0))) +#endif #endif /* NDEBUG */ diff --git a/lib/Support/assert.cpp b/lib/Support/assert.cpp index 73c2f11395..991ae01857 100644 --- a/lib/Support/assert.cpp +++ b/lib/Support/assert.cpp @@ -8,29 +8,37 @@ /////////////////////////////////////////////////////////////////////////////// #include "assert.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/raw_ostream.h" +namespace { +void llvm_assert_trap(const char *_Message, const char *_File, unsigned _Line, + const char *_Function) { + llvm::errs() << "Error: assert(" << _Message << ")\nFile:\n" + << _File << "(" << _Line << ")\nFunc:\t" << _Function << "\n"; + LLVM_BUILTIN_TRAP; +} +} // namespace #ifdef _WIN32 - #include "dxc/Support/Global.h" #include "windows.h" void llvm_assert(const char *Message, const char *File, unsigned Line, const char *Function) { +#ifdef LLVM_ASSERTIONS_TRAP + llvm_assert_trap(Message, File, Line, Function); +#else OutputDebugFormatA("Error: assert(%s)\nFile:\n%s(%d)\nFunc:\t%s\n", Message, File, Line, Function); RaiseException(STATUS_LLVM_ASSERT, 0, 0, 0); +#endif } -#else - -#include "llvm/Support/Compiler.h" -#include "llvm/Support/raw_ostream.h" +#else /* _WIN32 */ void llvm_assert(const char *Message, const char *File, unsigned Line, const char *Function) { - llvm::errs() << "Error: assert(" << Message << ")\nFile:\n" - << File << "(" << Line << ")\nFunc:\t" << Function << "\n"; - LLVM_BUILTIN_TRAP; + llvm_assert_trap(Message, File, Line, Function); } -#endif +#endif /* _WIN32 */