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.
pull/33/head
whitequark 2016-08-01 05:19:21 +00:00
parent 2fdbabc13c
commit 42d3ec9917
3 changed files with 23 additions and 11 deletions

View File

@ -4,6 +4,8 @@ if echo $TRAVIS_TAG | grep ^v; then BUILD_TYPE=RelWithDebInfo; else BUILD_TYPE=D
mkdir build
cd build
cmake -DCMAKE_C_COMPILER=gcc-5 -DCMAKE_CXX_COMPILER=g++-5 \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE -DENABLE_COVERAGE=ON ..
cmake .. -DCMAKE_C_COMPILER=gcc-5 -DCMAKE_CXX_COMPILER=g++-5 \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DENABLE_COVERAGE=ON \
-DENABLE_SANITIZERS=ON
make VERBOSE=1

View File

@ -27,10 +27,12 @@ set(solvespace_VERSION_MAJOR 3)
set(solvespace_VERSION_MINOR 0)
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")
set(ENABLE_COVERAGE OFF CACHE BOOL
set(ENABLE_COVERAGE OFF CACHE BOOL
"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)
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}")
endif()
if(SANITIZE)
if(ENABLE_SANITIZE)
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()
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} -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_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS}")
endif()

View File

@ -21,8 +21,8 @@ std::string LoadString(const std::string &name) {
}
std::string LoadStringFromGzip(const std::string &name) {
size_t size;
const void *data = LoadResource(name, &size);
size_t deflatedSize;
const void *data = LoadResource(name, &deflatedSize);
z_stream stream;
stream.zalloc = Z_NULL;
@ -33,11 +33,15 @@ std::string LoadStringFromGzip(const std::string &name) {
// Extract length mod 2**32 from the gzip trailer.
std::string result;
ssassert(size >= 4, "Resource too small to have gzip trailer");
result.resize(*(uint32_t *)((uintptr_t)data + size - 4));
ssassert(deflatedSize >= 4, "Resource too small to have gzip trailer");
// *(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.avail_in = size;
stream.avail_in = deflatedSize;
stream.next_out = (Bytef *)&result[0];
stream.avail_out = result.length();
ssassert(inflate(&stream, Z_NO_FLUSH) == Z_STREAM_END, "Cannot inflate resource");