CMake: finish Clang sanitizer support.
This makes ENABLE_SANITIZERS a proper cached variable, removes some spurious failures and configures asan/ubsan to die on an error.
This commit is contained in:
parent
2fdbabc13c
commit
42d3ec9917
@ -4,6 +4,8 @@ if echo $TRAVIS_TAG | grep ^v; then BUILD_TYPE=RelWithDebInfo; else BUILD_TYPE=D
|
|||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_C_COMPILER=gcc-5 -DCMAKE_CXX_COMPILER=g++-5 \
|
cmake .. -DCMAKE_C_COMPILER=gcc-5 -DCMAKE_CXX_COMPILER=g++-5 \
|
||||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE -DENABLE_COVERAGE=ON ..
|
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||||
|
-DENABLE_COVERAGE=ON \
|
||||||
|
-DENABLE_SANITIZERS=ON
|
||||||
make VERBOSE=1
|
make VERBOSE=1
|
||||||
|
@ -27,10 +27,12 @@ set(solvespace_VERSION_MAJOR 3)
|
|||||||
set(solvespace_VERSION_MINOR 0)
|
set(solvespace_VERSION_MINOR 0)
|
||||||
string(SUBSTRING "${GIT_COMMIT_HASH}" 0 8 solvespace_GIT_HASH)
|
string(SUBSTRING "${GIT_COMMIT_HASH}" 0 8 solvespace_GIT_HASH)
|
||||||
|
|
||||||
set(ENABLE_TESTS ON CACHE BOOL
|
set(ENABLE_TESTS ON CACHE BOOL
|
||||||
"Whether the test suite will be built and run")
|
"Whether the test suite will be built and run")
|
||||||
set(ENABLE_COVERAGE OFF CACHE BOOL
|
set(ENABLE_COVERAGE OFF CACHE BOOL
|
||||||
"Whether code coverage information will be collected")
|
"Whether code coverage information will be collected")
|
||||||
|
set(ENABLE_SANITIZERS OFF CACHE BOOL
|
||||||
|
"Whether to enable Clang's AddressSanitizer and UndefinedBehaviorSanitizer")
|
||||||
|
|
||||||
if(NOT WIN32 AND NOT APPLE)
|
if(NOT WIN32 AND NOT APPLE)
|
||||||
set(GUI gtk2 CACHE STRING "GUI toolkit to use (one of: gtk2 gtk3)")
|
set(GUI gtk2 CACHE STRING "GUI toolkit to use (one of: gtk2 gtk3)")
|
||||||
@ -58,12 +60,16 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
|||||||
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed ${CMAKE_EXE_LINKER_FLAGS}")
|
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed ${CMAKE_EXE_LINKER_FLAGS}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(SANITIZE)
|
if(ENABLE_SANITIZE)
|
||||||
if(NOT (CMAKE_C_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
|
if(NOT (CMAKE_C_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
|
||||||
message(ERROR "Sanitizers are only available in Clang/Clang++")
|
message(FATAL_ERROR "Sanitizers are only available when using Clang/Clang++")
|
||||||
endif()
|
endif()
|
||||||
set(SANITIZE_FLAGS "-O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
set(SANITIZE_FLAGS "-O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||||
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fsanitize=address,undefined,integer")
|
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fsanitize=address,undefined,integer")
|
||||||
|
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-sanitize-recover=undefined,integer")
|
||||||
|
# We assume IEEE floats, which means DIV/0 is defined; but ubsan doesn't do so by default.
|
||||||
|
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-sanitize=float-divide-by-zero")
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS}")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS}")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS}")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS}")
|
||||||
endif()
|
endif()
|
||||||
|
@ -21,8 +21,8 @@ std::string LoadString(const std::string &name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string LoadStringFromGzip(const std::string &name) {
|
std::string LoadStringFromGzip(const std::string &name) {
|
||||||
size_t size;
|
size_t deflatedSize;
|
||||||
const void *data = LoadResource(name, &size);
|
const void *data = LoadResource(name, &deflatedSize);
|
||||||
|
|
||||||
z_stream stream;
|
z_stream stream;
|
||||||
stream.zalloc = Z_NULL;
|
stream.zalloc = Z_NULL;
|
||||||
@ -33,11 +33,15 @@ std::string LoadStringFromGzip(const std::string &name) {
|
|||||||
|
|
||||||
// Extract length mod 2**32 from the gzip trailer.
|
// Extract length mod 2**32 from the gzip trailer.
|
||||||
std::string result;
|
std::string result;
|
||||||
ssassert(size >= 4, "Resource too small to have gzip trailer");
|
ssassert(deflatedSize >= 4, "Resource too small to have gzip trailer");
|
||||||
result.resize(*(uint32_t *)((uintptr_t)data + size - 4));
|
|
||||||
|
// *(uint32_t *) may perform an unaligned access, so do a memcpy.
|
||||||
|
uint32_t inflatedSize;
|
||||||
|
memcpy(&inflatedSize, (uint32_t *)((uintptr_t)data + deflatedSize - 4), sizeof(uint32_t));
|
||||||
|
result.resize(inflatedSize);
|
||||||
|
|
||||||
stream.next_in = (Bytef *)data;
|
stream.next_in = (Bytef *)data;
|
||||||
stream.avail_in = size;
|
stream.avail_in = deflatedSize;
|
||||||
stream.next_out = (Bytef *)&result[0];
|
stream.next_out = (Bytef *)&result[0];
|
||||||
stream.avail_out = result.length();
|
stream.avail_out = result.length();
|
||||||
ssassert(inflate(&stream, Z_NO_FLUSH) == Z_STREAM_END, "Cannot inflate resource");
|
ssassert(inflate(&stream, Z_NO_FLUSH) == Z_STREAM_END, "Cannot inflate resource");
|
||||||
|
Loading…
Reference in New Issue
Block a user