Fix component ownership.

When switching from raw pointers toward shared_ptr, the destructor
wasn't updated correctly.

This patch:
- Fixes the issue.
- Add two regression tests.
- Use address sanitizer for the tests.

This fixes: https://github.com/ArthurSonzogni/FTXUI/issues/115
This commit is contained in:
ArthurSonzogni 2021-06-21 22:49:42 +02:00 committed by Arthur Sonzogni
parent 478d7e8bca
commit 91c5954fe2
3 changed files with 42 additions and 1 deletions

View File

@ -231,6 +231,7 @@ if (FTXUI_BUILD_TESTS AND ${CMAKE_VERSION} VERSION_GREATER "3.11.4")
endif() endif()
add_executable(tests add_executable(tests
src/ftxui/component/component_test.cpp
src/ftxui/component/container_test.cpp src/ftxui/component/container_test.cpp
src/ftxui/component/input_test.cpp src/ftxui/component/input_test.cpp
src/ftxui/component/radiobox_test.cpp src/ftxui/component/radiobox_test.cpp
@ -252,6 +253,8 @@ if (FTXUI_BUILD_TESTS AND ${CMAKE_VERSION} VERSION_GREATER "3.11.4")
target_include_directories(tests target_include_directories(tests
PRIVATE src PRIVATE src
) )
target_compile_options(tests PRIVATE -fsanitize=address)
target_link_libraries(tests PRIVATE -fsanitize=address)
set_property(TARGET tests PROPERTY CXX_STANDARD 17) set_property(TARGET tests PROPERTY CXX_STANDARD 17)

View File

@ -19,7 +19,8 @@ class CaptureMouseImpl : public CapturedMouseInterface {
} // namespace } // namespace
ComponentBase::~ComponentBase() { ComponentBase::~ComponentBase() {
Detach(); while (children_.size() != 0)
children_.back()->Detach();
} }
/// @brief Return the parent ComponentBase, or nul if any. /// @brief Return the parent ComponentBase, or nul if any.
@ -142,6 +143,7 @@ void ComponentBase::Detach() {
return this == that.get(); return this == that.get();
}); });
parent_->children_.erase(it); parent_->children_.erase(it);
parent_ = nullptr;
} }
} // namespace ftxui } // namespace ftxui

View File

@ -0,0 +1,36 @@
#include <gtest/gtest-message.h> // for Message
#include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApiResolver, TestFactoryImpl
#include <memory> // for __shared_ptr_access, shared_ptr, allocator
#include "ftxui/component/component_base.hpp"
#include "gtest/gtest_pred_impl.h" // for AssertionResult, EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, Test, TEST
using namespace ftxui;
namespace {
Component Make() {
return std::make_shared<ComponentBase>();
}
} // namespace
// Regression test for:
// https://github.com/ArthurSonzogni/FTXUI/issues/115
TEST(ContainerTest, DeleteParentFirst) {
auto parent = Make();
auto child = Make();
parent->Add(child);
parent.reset();
child.reset();
}
TEST(ContainerTest, DeleteChildFirst) {
auto parent = Make();
auto child = Make();
parent->Add(child);
child.reset();
parent.reset();
}
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.