diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4321c28e..5bb022bb 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,3 +1,12 @@ +# 0.6-1 + +* fix CMake configuration error +* fix double free error in `segregator` +* add `static_assert()` when default constructing a stateful `std_allocator` +* fix various compiler warnings + +--- + # 0.6 ## Tool diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e9871ec..7d281b11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,8 @@ project(FOONATHAN_MEMORY) set(FOONATHAN_MEMORY_VERSION_MAJOR 0 CACHE STRING "major version of memory" FORCE) set(FOONATHAN_MEMORY_VERSION_MINOR 6 CACHE STRING "minor version of memory" FORCE) -set(FOONATHAN_MEMORY_VERSION "${FOONATHAN_MEMORY_VERSION_MAJOR}.${FOONATHAN_MEMORY_VERSION_MINOR}" +set(FOONATHAN_MEMORY_VERSION_PATCH 1 CACHE STRING "patch version of memory" FORCE) +set(FOONATHAN_MEMORY_VERSION "${FOONATHAN_MEMORY_VERSION_MAJOR}.${FOONATHAN_MEMORY_VERSION_MINOR}.${FOONATHAN_MEMORY_VERSION_PATCH}" CACHE STRING "version of memory" FORCE) include(cmake/compatibility.cmake) diff --git a/README.md b/README.md index 8c967bd9..03fc2970 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # memory -[![Build Status](https://travis-ci.org/foonathan/memory.svg?branch=master)](https://travis-ci.org/foonathan/memory) [![Build status](https://ci.appveyor.com/api/projects/status/ef654yqyoqgvl472/branch/master?svg=true)](https://ci.appveyor.com/project/foonathan/memory/branch/master) +[![Build Status](https://travis-ci.org/foonathan/memory.svg?branch=master)](https://travis-ci.org/foonathan/memory) [![Build status](https://ci.appveyor.com/api/projects/status/ef654yqyoqgvl472/branch/master?svg=true)](https://ci.appveyor.com/project/foonathan/memory/branch/master) [![License: Zlib](https://img.shields.io/badge/License-Zlib-lightgrey.svg)](https://opensource.org/licenses/Zlib) The C++ STL allocator model has various flaws. For example, they are fixed to a certain type, because they are almost necessarily required to be templates. So you can't easily share a single allocator for multiple types. In addition, you can only get a copy from the containers and not the original allocator object. At least with C++11 they are allowed to be stateful and so can be made object not instance based. But still, the model has many flaws. Over the course of the years many solutions have been proposed. for example [EASTL]. This library is another. But instead of trying to change the STL, it works with the current implementation. diff --git a/cmake/comp b/cmake/comp index 9d1a6fdb..cd142129 160000 --- a/cmake/comp +++ b/cmake/comp @@ -1 +1 @@ -Subproject commit 9d1a6fdb6cf2d9d88f280a8b893c23123bccd506 +Subproject commit cd142129e30f5b3e6c6d96310daf94242c0b03bf diff --git a/include/foonathan/memory/error.hpp b/include/foonathan/memory/error.hpp index e1f08cbe..c13dd5bc 100644 --- a/include/foonathan/memory/error.hpp +++ b/include/foonathan/memory/error.hpp @@ -35,23 +35,22 @@ namespace foonathan const void* allocator; /// \effects Creates it by giving it the name of the allocator and a pointer. - FOONATHAN_CONSTEXPR allocator_info(const char *name, - const void *allocator) FOONATHAN_NOEXCEPT - : name(name), - allocator(allocator) + FOONATHAN_CONSTEXPR_FNC allocator_info(const char* n, const void* alloc) FOONATHAN_NOEXCEPT + : name(n), + allocator(alloc) { } /// @{ /// \effects Compares two \ref allocator_info objects, they are equal, if the \ref allocator is the same. /// \returns The result of the comparision. - friend FOONATHAN_CONSTEXPR bool operator==(const allocator_info& a, + friend FOONATHAN_CONSTEXPR_FNC bool operator==(const allocator_info& a, const allocator_info& b) FOONATHAN_NOEXCEPT { return a.allocator == b.allocator; } - friend FOONATHAN_CONSTEXPR bool operator!=(const allocator_info& a, + friend FOONATHAN_CONSTEXPR_FNC bool operator!=(const allocator_info& a, const allocator_info& b) FOONATHAN_NOEXCEPT { return a.allocator != b.allocator; diff --git a/include/foonathan/memory/joint_allocator.hpp b/include/foonathan/memory/joint_allocator.hpp index 4b38c68e..e2635b88 100644 --- a/include/foonathan/memory/joint_allocator.hpp +++ b/include/foonathan/memory/joint_allocator.hpp @@ -102,7 +102,7 @@ namespace foonathan /// \ingroup memory allocator class joint { - joint(std::size_t capacity) FOONATHAN_NOEXCEPT : capacity(capacity) + joint(std::size_t cap) FOONATHAN_NOEXCEPT : capacity(cap) { } @@ -122,7 +122,7 @@ namespace foonathan { std::size_t size; - explicit joint_size(std::size_t size) FOONATHAN_NOEXCEPT : size(size) + explicit joint_size(std::size_t s) FOONATHAN_NOEXCEPT : size(s) { } }; diff --git a/include/foonathan/memory/memory_arena.hpp b/include/foonathan/memory/memory_arena.hpp index da738ef3..84c15cd5 100644 --- a/include/foonathan/memory/memory_arena.hpp +++ b/include/foonathan/memory/memory_arena.hpp @@ -38,7 +38,7 @@ namespace foonathan } /// \effects Creates a memory block from a given starting address and size. - memory_block(void* mem, std::size_t size) FOONATHAN_NOEXCEPT : memory(mem), size(size) + memory_block(void* mem, std::size_t s) FOONATHAN_NOEXCEPT : memory(mem), size(s) { } @@ -169,8 +169,7 @@ namespace foonathan node* prev; std::size_t usable_size; - node(node* prev, std::size_t size) FOONATHAN_NOEXCEPT : prev(prev), - usable_size(size) + node(node* p, std::size_t size) FOONATHAN_NOEXCEPT : prev(p), usable_size(size) { } diff --git a/include/foonathan/memory/memory_stack.hpp b/include/foonathan/memory/memory_stack.hpp index 9ade2f17..440c7db3 100644 --- a/include/foonathan/memory/memory_stack.hpp +++ b/include/foonathan/memory/memory_stack.hpp @@ -35,9 +35,9 @@ namespace foonathan const char* end; stack_marker(std::size_t i, const detail::fixed_memory_stack& s, - const char* end) FOONATHAN_NOEXCEPT : index(i), - top(s.top()), - end(end) + const char* e) FOONATHAN_NOEXCEPT : index(i), + top(s.top()), + end(e) { } diff --git a/include/foonathan/memory/segregator.hpp b/include/foonathan/memory/segregator.hpp index 0c6adc58..452f3d1e 100644 --- a/include/foonathan/memory/segregator.hpp +++ b/include/foonathan/memory/segregator.hpp @@ -124,8 +124,8 @@ namespace foonathan /// \ingroup memory adapter template class binary_segregator - : FOONATHAN_EBO( - detail::ebo_storage<1, typename allocator_traits::allocator_type>) + : FOONATHAN_EBO( + detail::ebo_storage<1, typename allocator_traits::allocator_type>) { using segregatable_traits = allocator_traits; using fallback_traits = allocator_traits; @@ -152,7 +152,9 @@ namespace foonathan if (get_segregatable().use_allocate_node(size, alignment)) return segregatable_traits::allocate_node(get_segregatable_allocator(), size, alignment); - return fallback_traits::allocate_node(get_fallback_allocator(), size, alignment); + else + return fallback_traits::allocate_node(get_fallback_allocator(), size, + alignment); } void deallocate_node(void* ptr, std::size_t size, @@ -161,7 +163,9 @@ namespace foonathan if (get_segregatable().use_allocate_node(size, alignment)) segregatable_traits::deallocate_node(get_segregatable_allocator(), ptr, size, alignment); - fallback_traits::deallocate_node(get_fallback_allocator(), ptr, size, alignment); + else + fallback_traits::deallocate_node(get_fallback_allocator(), ptr, size, + alignment); } void* allocate_array(std::size_t count, std::size_t size, std::size_t alignment) @@ -169,8 +173,9 @@ namespace foonathan if (get_segregatable().use_allocate_array(count, size, alignment)) return segregatable_traits::allocate_array(get_segregatable_allocator(), count, size, alignment); - return fallback_traits::allocate_array(get_fallback_allocator(), count, size, - alignment); + else + return fallback_traits::allocate_array(get_fallback_allocator(), count, size, + alignment); } void deallocate_array(void* array, std::size_t count, std::size_t size, @@ -179,8 +184,9 @@ namespace foonathan if (get_segregatable().use_allocate_array(count, size, alignment)) segregatable_traits::deallocate_array(get_segregatable_allocator(), array, count, size, alignment); - fallback_traits::deallocate_array(get_fallback_allocator(), array, count, size, - alignment); + else + fallback_traits::deallocate_array(get_fallback_allocator(), array, count, size, + alignment); } /// @} diff --git a/include/foonathan/memory/std_allocator.hpp b/include/foonathan/memory/std_allocator.hpp index 444fe432..bd87b82d 100644 --- a/include/foonathan/memory/std_allocator.hpp +++ b/include/foonathan/memory/std_allocator.hpp @@ -112,6 +112,12 @@ namespace foonathan /// \requires The \c RawAllocator type is stateless, otherwise the body of this function will not compile. std_allocator() FOONATHAN_NOEXCEPT : alloc_reference(allocator_type{}) { +#if !defined(__GNUC__) || (defined(_GLIBCXX_USE_CXX11_ABI) && _GLIBCXX_USE_CXX11_ABI != 0) + // std::string requires default constructor for the small string optimization when using gcc's old ABI + // so don't assert then to allow joint allocator + static_assert(!alloc_reference::is_stateful::value, + "default constructor must not be used for stateful allocators"); +#endif } /// \effects Creates it from a reference to a \c RawAllocator. @@ -121,13 +127,14 @@ namespace foonathan /// If the requirement is not fulfilled this function does not participate in overload resolution. /// \note The caller has to ensure that the lifetime of the \c RawAllocator is at least as long as the lifetime /// of this \ref std_allocator object. - template ::value))> + template < + class RawAlloc, + // MSVC seems to ignore access rights in decltype SFINAE below + // use this to prevent this constructor being chosen instead of move/copy for types inheriting from it + FOONATHAN_REQUIRES((!std::is_base_of::value))> std_allocator(RawAlloc& alloc, FOONATHAN_SFINAE(alloc_reference(alloc))) FOONATHAN_NOEXCEPT - : alloc_reference(alloc) + : alloc_reference(alloc) { } @@ -136,13 +143,14 @@ namespace foonathan /// \requires The \c RawAllocator is stateless /// and the expression allocator_reference(alloc) is well-formed as above, /// otherwise this function does not participate in overload resolution. - template ::value))> + template < + class RawAlloc, + // MSVC seems to ignore access rights in decltype SFINAE below + // use this to prevent this constructor being chosen instead of move/copy for types inheriting from it + FOONATHAN_REQUIRES((!std::is_base_of::value))> std_allocator(const RawAlloc& alloc, FOONATHAN_SFINAE(alloc_reference(alloc))) FOONATHAN_NOEXCEPT - : alloc_reference(alloc) + : alloc_reference(alloc) { } @@ -161,13 +169,13 @@ namespace foonathan /// This is required by the \c Allcoator concept and simply takes the same \ref allocator_reference. template std_allocator(const std_allocator& alloc) FOONATHAN_NOEXCEPT - : alloc_reference(alloc.get_allocator()) + : alloc_reference(alloc.get_allocator()) { } template std_allocator(std_allocator& alloc) FOONATHAN_NOEXCEPT - : alloc_reference(alloc.get_allocator()) + : alloc_reference(alloc.get_allocator()) { } /// @} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 37dcc49b..6fad558f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,7 @@ set(detail_header ${header_path}/detail/assert.hpp ${header_path}/detail/container_node_sizes.hpp ${header_path}/detail/debug_helpers.hpp + ${header_path}/detail/ebo_storage.hpp ${header_path}/detail/free_list.hpp ${header_path}/detail/free_list_array.hpp ${header_path}/detail/lowlevel_allocator.hpp @@ -88,6 +89,7 @@ endif() add_library(foonathan_memory ${detail_header} ${header} ${src}) _foonathan_use_comp(foonathan_memory) +comp_target_features(foonathan_memory PRIVATE CPP11) target_include_directories(foonathan_memory PUBLIC $ # for client in subdirectory $ # for generated files in build mode $ # for client in install mode @@ -96,7 +98,8 @@ target_include_directories(foonathan_memory PUBLIC $next; @@ -358,7 +358,7 @@ chunk* small_free_memory_list::find_chunk_impl(std::size_t n) FOONATHAN_NOEXCEPT { if (auto c = make_chunk(cur_forward, n)) return c; - else if (auto c = make_chunk(cur_backward, n)) + else if ((c = make_chunk(cur_backward, n)) != nullptr) return c; cur_forward = cur_forward->next; @@ -379,7 +379,7 @@ chunk* small_free_memory_list::find_chunk_impl(unsigned char* node, chunk_base* { if (auto c = from_chunk(first, node, actual_size)) return c; - else if (auto c = from_chunk(last, node, actual_size)) + else if ((c = from_chunk(last, node, actual_size)) != nullptr) return c; first = first->next; @@ -394,7 +394,7 @@ chunk* small_free_memory_list::find_chunk_impl(unsigned char* node) FOONATHAN_NO if (auto c = from_chunk(dealloc_chunk_, node, actual_size)) return c; - else if (auto c = from_chunk(alloc_chunk_, node, actual_size)) + else if ((c = from_chunk(alloc_chunk_, node, actual_size)) != nullptr) return c; else if (less(dealloc_chunk_, node)) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 989503d9..bb1da72f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -49,6 +49,7 @@ set(tests segregator.cpp) add_executable(foonathan_memory_test ${tests}) +comp_target_features(foonathan_memory_test PUBLIC CPP11) target_link_libraries(foonathan_memory_test foonathan_memory) target_include_directories(foonathan_memory_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR} diff --git a/test/default_allocator.cpp b/test/default_allocator.cpp index e7f1c2ce..f9235601 100644 --- a/test/default_allocator.cpp +++ b/test/default_allocator.cpp @@ -23,21 +23,21 @@ void check_default_allocator(Allocator& alloc, std::size_t def_alignment = detai for (std::size_t i = 0u; i != 10u; ++i) { - auto ptr = alloc.allocate_node(i, 1); - REQUIRE(detail::is_aligned(ptr, def_alignment)); - alloc.deallocate_node(ptr, i, 1); + auto node = alloc.allocate_node(i, 1); + REQUIRE(detail::is_aligned(node, def_alignment)); + alloc.deallocate_node(node, i, 1); } - std::vector ptrs; + std::vector nodes; for (std::size_t i = 0u; i != 10u; ++i) { - auto ptr = alloc.allocate_node(i, 1); - REQUIRE(detail::is_aligned(ptr, def_alignment)); - ptrs.push_back(ptr); + auto node = alloc.allocate_node(i, 1); + REQUIRE(detail::is_aligned(node, def_alignment)); + nodes.push_back(node); } for (std::size_t i = 0u; i != 10u; ++i) - alloc.deallocate_node(ptrs[i], i, 1); + alloc.deallocate_node(nodes[i], i, 1); } TEST_CASE("heap_allocator", "[default_allocator]") diff --git a/test/detail/free_list.cpp b/test/detail/free_list.cpp index 0c2378fe..f0f497e7 100644 --- a/test/detail/free_list.cpp +++ b/test/detail/free_list.cpp @@ -112,11 +112,15 @@ TEST_CASE("free_memory_list", "[detail][pool]") { static_allocator_storage<1024> memory; check_list(list, &memory, 1024); + + check_move(list); } SECTION("uneven insert") { static_allocator_storage<1023> memory; // not dividable check_list(list, &memory, 1023); + + check_move(list); } SECTION("multiple insert") { @@ -126,8 +130,9 @@ TEST_CASE("free_memory_list", "[detail][pool]") check_list(list, &a, 1024); check_list(list, &b, 100); check_list(list, &c, 1337); + + check_move(list); } - check_move(list); } void use_list_array(ordered_free_memory_list& list) @@ -173,12 +178,16 @@ TEST_CASE("ordered_free_memory_list", "[detail][pool]") static_allocator_storage<1024> memory; check_list(list, &memory, 1024); use_list_array(list); + + check_move(list); } SECTION("uneven insert") { static_allocator_storage<1023> memory; // not dividable check_list(list, &memory, 1023); use_list_array(list); + + check_move(list); } SECTION("multiple insert") { @@ -191,8 +200,9 @@ TEST_CASE("ordered_free_memory_list", "[detail][pool]") use_list_array(list); check_list(list, &c, 1337); use_list_array(list); + + check_move(list); } - check_move(list); } TEST_CASE("small_free_memory_list", "[detail][pool]") @@ -206,16 +216,22 @@ TEST_CASE("small_free_memory_list", "[detail][pool]") { static_allocator_storage<1024> memory; check_list(list, &memory, 1024); + + check_move(list); } SECTION("uneven insert") { static_allocator_storage<1023> memory; // not dividable check_list(list, &memory, 1023); + + check_move(list); } SECTION("big insert") { static_allocator_storage<4096> memory; // should use multiple chunks check_list(list, &memory, 4096); + + check_move(list); } SECTION("multiple insert") { @@ -225,6 +241,7 @@ TEST_CASE("small_free_memory_list", "[detail][pool]") check_list(list, &a, 1024); check_list(list, &b, 100); check_list(list, &c, 1337); + + check_move(list); } - check_move(list); } diff --git a/test/iteration_allocator.cpp b/test/iteration_allocator.cpp index 21125024..adcfb175 100644 --- a/test/iteration_allocator.cpp +++ b/test/iteration_allocator.cpp @@ -21,9 +21,9 @@ TEST_CASE("iteration_allocator", "[stack]") REQUIRE(iter_alloc.capacity_left(0u) == 50); REQUIRE(iter_alloc.capacity_left(1u) == 50); - auto mem = iter_alloc.allocate(10, 1); + iter_alloc.allocate(10, 1); REQUIRE(iter_alloc.capacity_left() < 50); - auto mem2 = iter_alloc.allocate(4, 4); + iter_alloc.allocate(4, 4); REQUIRE(iter_alloc.capacity_left() < 50); REQUIRE(iter_alloc.capacity_left(1u) == 50); @@ -32,7 +32,7 @@ TEST_CASE("iteration_allocator", "[stack]") REQUIRE(iter_alloc.capacity_left() == 50); REQUIRE(iter_alloc.capacity_left(0u) < 50); - mem = iter_alloc.allocate(10, 1); + iter_alloc.allocate(10, 1); REQUIRE(iter_alloc.capacity_left() < 50); iter_alloc.next_iteration(); diff --git a/test/joint_allocator.cpp b/test/joint_allocator.cpp index 6d5c7c89..4e484a75 100644 --- a/test/joint_allocator.cpp +++ b/test/joint_allocator.cpp @@ -184,8 +184,8 @@ TEST_CASE("joint_allocator", "[allocator]") vector vec; int value; - joint_test(joint tag, int value, std::size_t size) - : joint_type(tag), vec(*this), value(value) + joint_test(joint tag, int val, std::size_t size) + : joint_type(tag), vec(*this), value(val) { vec.reserve(size); vec.push_back(42); diff --git a/test/memory_arena.cpp b/test/memory_arena.cpp index d2951a9f..d3c6a8bd 100644 --- a/test/memory_arena.cpp +++ b/test/memory_arena.cpp @@ -40,10 +40,10 @@ TEST_CASE("detail::memory_block_stack", "[detail][arena]") REQUIRE(stack.empty()); REQUIRE(!other.empty()); - auto top = other.top(); - REQUIRE(top.memory >= static_cast(&memory)); - REQUIRE(top.size <= 1024); - REQUIRE(is_aligned(top.memory, max_alignment)); + auto other_top = other.top(); + REQUIRE(other_top.memory >= static_cast(&memory)); + REQUIRE(other_top.size <= 1024); + REQUIRE(is_aligned(other_top.memory, max_alignment)); } static_allocator_storage<1024> a, b, c; diff --git a/test/memory_stack.cpp b/test/memory_stack.cpp index 14021bbe..9bd9f36d 100644 --- a/test/memory_stack.cpp +++ b/test/memory_stack.cpp @@ -120,10 +120,10 @@ TEST_CASE("memory_stack", "[stack]") REQUIRE(unwind.will_unwind()); { - memory_stack_raii_unwind unwind(stack); + memory_stack_raii_unwind unwind2(stack); stack.allocate(10, 1); - unwind.release(); - REQUIRE(!unwind.will_unwind()); + unwind2.release(); + REQUIRE(!unwind2.will_unwind()); } REQUIRE(stack.top() > m); m = stack.top(); diff --git a/test/segregator.cpp b/test/segregator.cpp index de752531..530590c6 100644 --- a/test/segregator.cpp +++ b/test/segregator.cpp @@ -36,36 +36,50 @@ TEST_CASE("binary_segregator", "[adapter]") segregator s(threshold(8u, test_allocator{})); REQUIRE(s.get_segregatable_allocator().no_allocated() == 0u); REQUIRE(s.get_fallback_allocator().no_allocated() == 0u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 0u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 0u); auto ptr = s.allocate_node(1u, 1u); REQUIRE(s.get_segregatable_allocator().no_allocated() == 1u); REQUIRE(s.get_fallback_allocator().no_allocated() == 0u); s.deallocate_node(ptr, 1u, 1u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 1u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 0u); ptr = s.allocate_node(8u, 1u); REQUIRE(s.get_segregatable_allocator().no_allocated() == 1u); REQUIRE(s.get_fallback_allocator().no_allocated() == 0u); s.deallocate_node(ptr, 8u, 1u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 2u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 0u); ptr = s.allocate_node(8u, 1u); REQUIRE(s.get_segregatable_allocator().no_allocated() == 1u); REQUIRE(s.get_fallback_allocator().no_allocated() == 0u); s.deallocate_node(ptr, 8u, 1u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 3u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 0u); ptr = s.allocate_node(9u, 1u); REQUIRE(s.get_segregatable_allocator().no_allocated() == 0u); REQUIRE(s.get_fallback_allocator().no_allocated() == 1u); s.deallocate_node(ptr, 9u, 1u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 3u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 1u); ptr = s.allocate_array(1u, 8u, 1u); REQUIRE(s.get_segregatable_allocator().no_allocated() == 1u); REQUIRE(s.get_fallback_allocator().no_allocated() == 0u); s.deallocate_array(ptr, 1u, 8u, 1u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 4u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 1u); ptr = s.allocate_array(2u, 8u, 1u); REQUIRE(s.get_segregatable_allocator().no_allocated() == 0u); REQUIRE(s.get_fallback_allocator().no_allocated() == 1u); s.deallocate_array(ptr, 2u, 8u, 1u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 4u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 2u); } TEST_CASE("segregator", "[adapter]") diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt index 4905436b..5702f851 100644 --- a/tool/CMakeLists.txt +++ b/tool/CMakeLists.txt @@ -6,6 +6,7 @@ add_executable(foonathan_memory_node_size_debugger test_types.hpp node_size_debugger.hpp node_size_debugger.cpp) _foonathan_use_comp(foonathan_memory_node_size_debugger) +comp_target_features(foonathan_memory_node_size_debugger PUBLIC CPP11) target_compile_definitions(foonathan_memory_node_size_debugger PUBLIC VERSION="${FOONATHAN_MEMORY_VERSION_MAJOR}.${FOONATHAN_MEMORY_VERSION_MINOR}") set_target_properties(foonathan_memory_node_size_debugger PROPERTIES OUTPUT_NAME nodesize_dbg)