Commit 09b91406 authored by Niels Lohmann's avatar Niels Lohmann Committed by GitHub

🔀 merge pull request #410 from Daniel599/feature/clang_sanitize

Feature/clang sanitize
parents ab7d55e7 ff3221a3
...@@ -42,14 +42,20 @@ matrix: ...@@ -42,14 +42,20 @@ matrix:
- make check TEST_PREFIX="valgrind --error-exitcode=1 --leak-check=full " TEST_PATTERN="" - make check TEST_PREFIX="valgrind --error-exitcode=1 --leak-check=full " TEST_PATTERN=""
# cLang sanitizer # cLang sanitizer
# note: sadly clang's libc++ has errors when running with sanitize,
#- os: linux # so we use clang with gcc's libstdc++ which doesn't give those error.
# env: # that's why we need to install g++-6 to get the lastest version
# - LLVM_VERSION=3.8.1 - os: linux
# - SPECIAL=sanitizer env:
# compiler: clang - LLVM_VERSION=3.8.1
# before_script: - SPECIAL=sanitizer
# - make clang_sanitize addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: g++-6
compiler: clang
before_script:
- make clang_sanitize
# cppcheck # cppcheck
......
...@@ -92,8 +92,9 @@ fuzzing-stop: ...@@ -92,8 +92,9 @@ fuzzing-stop:
cppcheck: cppcheck:
cppcheck --enable=warning --inconclusive --force --std=c++11 src/json.hpp --error-exitcode=1 cppcheck --enable=warning --inconclusive --force --std=c++11 src/json.hpp --error-exitcode=1
# run clang sanitize (we are overrding the CXXFLAGS provided by travis in order to use gcc's libstdc++)
clang_sanitize: clean clang_sanitize: clean
CXX=clang++ CXXFLAGS="-g -O2 -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer" $(MAKE) CXX=clang++ CXXFLAGS="-g -O2 -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer" $(MAKE) check -C test
########################################################################## ##########################################################################
......
...@@ -111,6 +111,16 @@ struct my_allocator : std::allocator<T> ...@@ -111,6 +111,16 @@ struct my_allocator : std::allocator<T>
} }
}; };
// allows deletion of raw pointer, usually hold by json_value
template<class T>
void my_allocator_clean_up(T* p)
{
assert(p != nullptr);
my_allocator<T> alloc;
alloc.destroy(p);
alloc.deallocate(p, 1);
}
TEST_CASE("controlled bad_alloc") TEST_CASE("controlled bad_alloc")
{ {
// create JSON type using the throwing allocator // create JSON type using the throwing allocator
...@@ -131,7 +141,8 @@ TEST_CASE("controlled bad_alloc") ...@@ -131,7 +141,8 @@ TEST_CASE("controlled bad_alloc")
{ {
next_construct_fails = false; next_construct_fails = false;
auto t = my_json::value_t::object; auto t = my_json::value_t::object;
CHECK_NOTHROW(my_json::json_value j(t)); auto clean_up = [](my_json::json_value& j){ my_allocator_clean_up(j.object); };
CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
next_construct_fails = true; next_construct_fails = true;
CHECK_THROWS_AS(my_json::json_value j(t), std::bad_alloc); CHECK_THROWS_AS(my_json::json_value j(t), std::bad_alloc);
next_construct_fails = false; next_construct_fails = false;
...@@ -140,7 +151,8 @@ TEST_CASE("controlled bad_alloc") ...@@ -140,7 +151,8 @@ TEST_CASE("controlled bad_alloc")
{ {
next_construct_fails = false; next_construct_fails = false;
auto t = my_json::value_t::array; auto t = my_json::value_t::array;
CHECK_NOTHROW(my_json::json_value j(t)); auto clean_up = [](my_json::json_value& j){ my_allocator_clean_up(j.array); };
CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
next_construct_fails = true; next_construct_fails = true;
CHECK_THROWS_AS(my_json::json_value j(t), std::bad_alloc); CHECK_THROWS_AS(my_json::json_value j(t), std::bad_alloc);
next_construct_fails = false; next_construct_fails = false;
...@@ -149,7 +161,8 @@ TEST_CASE("controlled bad_alloc") ...@@ -149,7 +161,8 @@ TEST_CASE("controlled bad_alloc")
{ {
next_construct_fails = false; next_construct_fails = false;
auto t = my_json::value_t::string; auto t = my_json::value_t::string;
CHECK_NOTHROW(my_json::json_value j(t)); auto clean_up = [](my_json::json_value& j){ my_allocator_clean_up(j.string); };
CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
next_construct_fails = true; next_construct_fails = true;
CHECK_THROWS_AS(my_json::json_value j(t), std::bad_alloc); CHECK_THROWS_AS(my_json::json_value j(t), std::bad_alloc);
next_construct_fails = false; next_construct_fails = false;
...@@ -160,7 +173,8 @@ TEST_CASE("controlled bad_alloc") ...@@ -160,7 +173,8 @@ TEST_CASE("controlled bad_alloc")
{ {
next_construct_fails = false; next_construct_fails = false;
my_json::string_t v("foo"); my_json::string_t v("foo");
CHECK_NOTHROW(my_json::json_value j(v)); auto clean_up = [](my_json::json_value& j){ my_allocator_clean_up(j.string); };
CHECK_NOTHROW(my_json::json_value j(v); clean_up(j));
next_construct_fails = true; next_construct_fails = true;
CHECK_THROWS_AS(my_json::json_value j(v), std::bad_alloc); CHECK_THROWS_AS(my_json::json_value j(v), std::bad_alloc);
next_construct_fails = false; next_construct_fails = false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment