mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-25 17:25:08 +02:00
AK+Tests: Destroy moved-from CallableWrappers
We won't attempt to destroy this wrapper later because m_kind gets set to NullPointer. If any fields of the CallableType are not movable, this results in a leak. A test replicating the issue before the fix is added to a new TestFunction.cpp file.
This commit is contained in:
committed by
Gregory Bertilson
parent
a0052316e5
commit
d5bf929699
Notes:
github-actions[bot]
2026-02-18 19:15:57 +00:00
Author: https://github.com/Zaggy1024 Commit: https://github.com/LadybirdBrowser/ladybird/commit/d5bf9296992 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/7922
@@ -357,6 +357,7 @@ private:
|
||||
case FunctionKind::Inline:
|
||||
case FunctionKind::Block:
|
||||
other_wrapper->init_and_swap(m_storage, inline_capacity);
|
||||
other_wrapper->~CallableWrapperBase();
|
||||
m_kind = other.m_kind;
|
||||
break;
|
||||
case FunctionKind::Outline:
|
||||
|
||||
@@ -27,6 +27,7 @@ set(AK_TEST_SOURCES
|
||||
TestFind.cpp
|
||||
TestFixedArray.cpp
|
||||
TestFixedPoint.cpp
|
||||
TestFunction.cpp
|
||||
TestFlyString.cpp
|
||||
TestFormat.cpp
|
||||
TestGenericLexer.cpp
|
||||
|
||||
77
Tests/AK/TestFunction.cpp
Normal file
77
Tests/AK/TestFunction.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Gregory Bertilson <gregory@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibTest/TestCase.h>
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/RefCounted.h>
|
||||
|
||||
namespace {
|
||||
|
||||
struct CopyOnly {
|
||||
int& instance_count;
|
||||
|
||||
CopyOnly(int& count)
|
||||
: instance_count(count)
|
||||
{
|
||||
instance_count++;
|
||||
}
|
||||
|
||||
CopyOnly(CopyOnly const& other)
|
||||
: instance_count(other.instance_count)
|
||||
{
|
||||
instance_count++;
|
||||
}
|
||||
|
||||
~CopyOnly()
|
||||
{
|
||||
instance_count--;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE(move_construction_destroys_old_inline_wrapper)
|
||||
{
|
||||
int instance_count = 0;
|
||||
|
||||
{
|
||||
Function<void()> source = [captured = CopyOnly(instance_count)]() {
|
||||
(void)captured;
|
||||
};
|
||||
EXPECT_EQ(instance_count, 1);
|
||||
|
||||
Function<void()> destination = move(source);
|
||||
EXPECT_EQ(instance_count, 1);
|
||||
|
||||
source = nullptr;
|
||||
EXPECT_EQ(instance_count, 1);
|
||||
}
|
||||
|
||||
EXPECT_EQ(instance_count, 0);
|
||||
}
|
||||
|
||||
TEST_CASE(move_assignment_destroys_old_inline_wrapper)
|
||||
{
|
||||
int instance_count = 0;
|
||||
|
||||
{
|
||||
Function<void()> source = [captured = CopyOnly(instance_count)]() {
|
||||
(void)captured;
|
||||
};
|
||||
EXPECT_EQ(instance_count, 1);
|
||||
|
||||
Function<void()> destination;
|
||||
destination = move(source);
|
||||
EXPECT_EQ(instance_count, 1);
|
||||
|
||||
source = nullptr;
|
||||
EXPECT_EQ(instance_count, 1);
|
||||
}
|
||||
|
||||
EXPECT_EQ(instance_count, 0);
|
||||
}
|
||||
Reference in New Issue
Block a user