Fix delegate not being cleared by assigning empty braces (#1401)

* Fix delegate not being cleared by assigning empty braces

Fixes issue #1399.

The non-capturing lambda support (PR#1295) added a non-explicit
delegate(function_ptr) constructor and operator=(function_ptr). This
caused `delegate = {}` to implicitly convert `{}` to a null function
pointer and bind it via function_ptr_stub, leaving the delegate
appearing valid (stub != nullptr) but invoking through a null pointer
(undefined behavior).

Fix:
- Mark delegate(function_ptr) constructor explicit to prevent implicit
  conversion from `{}` during initialization.
- In operator=(function_ptr), clear the delegate when fp is null
  instead of binding a null pointer through function_ptr_stub.

Added tests verifying that both `delegate d = {}` and `d = {}` produce
an invalid (cleared) delegate.

* Fix Dockerfile for powerpc cross build

Debian snapshot sources were mixed with plain sid sources which
mismatched after a while. Now, aligning all sources from snapshot
server.
This commit is contained in:
Roland Reichwein 2026-04-21 15:27:43 +02:00 committed by GitHub
parent bbf74c5334
commit b860326b26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 38 additions and 2 deletions

View File

@ -20,6 +20,14 @@ RUN dpkg --add-architecture powerpc && \
debian-ports-archive-keyring \
&& rm -rf /var/lib/apt/lists/*
RUN cat <<EOF > /etc/apt/sources.list.d/debian.sources
Types: deb
URIs: http://snapshot.debian.org/archive/debian/20260406T000000Z
Suites: sid
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp
EOF
RUN cat <<EOF > /etc/apt/sources.list.d/powerpc.sources
Types: deb
URIs: http://snapshot.debian.org/archive/debian-ports/20260406T000000Z

View File

@ -172,7 +172,7 @@ namespace etl
//*************************************************************************
// Construct from a function pointer.
//*************************************************************************
delegate(function_ptr fp) ETL_NOEXCEPT
explicit delegate(function_ptr fp) ETL_NOEXCEPT
{
assign(fp, function_ptr_stub);
}
@ -534,7 +534,14 @@ namespace etl
//*************************************************************************
delegate& operator=(function_ptr fp) ETL_NOEXCEPT
{
assign(fp, function_ptr_stub);
if (fp == ETL_NULLPTR)
{
invocation.clear();
}
else
{
assign(fp, function_ptr_stub);
}
return *this;
}

View File

@ -372,6 +372,27 @@ namespace
CHECK_FALSE(d.is_valid());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_is_valid_after_init_empty_braces)
{
etl::delegate<void(void)> d = {};
CHECK_FALSE(d.is_valid());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_is_valid_after_assign_empty_braces)
{
auto lambda = [] {
};
etl::delegate<void(void)> d(lambda);
CHECK_TRUE(d.is_valid());
d = {};
CHECK_FALSE(d.is_valid());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_free_void)
{