mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-11 18:50:50 +00:00
LibWasm: Fix UB in LibWasm
Now that `Optional<T&>` are trivially copyable/movable, it is triggering Undefined Behaviour checks on GCC. We can resolve those by using an union.
This commit is contained in:
parent
55383998b1
commit
d7a721951e
Notes:
github-actions[bot]
2024-12-04 00:59:38 +00:00
Author: https://github.com/yyny
Commit: d7a721951e
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2567
Reviewed-by: https://github.com/alimpfard
Reviewed-by: https://github.com/gmta ✅
1 changed files with 18 additions and 15 deletions
|
@ -738,30 +738,31 @@ static_assert(sizeof(SockRecvResult) == 8);
|
||||||
template<typename TResult, typename Tag = u32>
|
template<typename TResult, typename Tag = u32>
|
||||||
struct Result {
|
struct Result {
|
||||||
Result(TResult&& result)
|
Result(TResult&& result)
|
||||||
: bits {}
|
: m_result(result)
|
||||||
, tag(0)
|
, tag(0)
|
||||||
{
|
{
|
||||||
new (&bits) TResult(move(result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result(Errno&& error)
|
Result(Errno&& error)
|
||||||
: bits {}
|
: m_error(error)
|
||||||
, tag(1)
|
, tag(1)
|
||||||
{
|
{
|
||||||
new (&bits) Errno(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<TResult&> result() const
|
static_assert(IsTriviallyDestructible<TResult>);
|
||||||
|
static_assert(IsTriviallyDestructible<Errno>);
|
||||||
|
|
||||||
|
Optional<TResult const&> result() const
|
||||||
{
|
{
|
||||||
if (tag == 0)
|
if (tag == 0)
|
||||||
return *bit_cast<TResult*>(&bits[0]);
|
return m_result;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Errno&> error() const
|
Optional<Errno const&> error() const
|
||||||
{
|
{
|
||||||
if (tag == 1)
|
if (tag == 1)
|
||||||
return *bit_cast<Errno*>(&bits[0]);
|
return m_error;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,23 +779,25 @@ struct Result {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
alignas(max(alignof(TResult), alignof(Errno))) u8 bits[max(sizeof(TResult), sizeof(Errno))];
|
union {
|
||||||
|
TResult m_result;
|
||||||
|
Errno m_error;
|
||||||
|
};
|
||||||
LittleEndian<Tag> tag;
|
LittleEndian<Tag> tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Tag>
|
template<typename Tag>
|
||||||
struct Result<void, Tag> {
|
struct Result<void, Tag> {
|
||||||
Result()
|
Result()
|
||||||
: error_bits {}
|
: m_error()
|
||||||
, tag(0)
|
, tag(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Result(Errno&& error)
|
Result(Errno&& error)
|
||||||
: error_bits {}
|
: m_error(error)
|
||||||
, tag(1)
|
, tag(1)
|
||||||
{
|
{
|
||||||
new (&error_bits) Errno(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Empty> result() const
|
Optional<Empty> result() const
|
||||||
|
@ -803,16 +806,16 @@ struct Result<void, Tag> {
|
||||||
return { Empty {} };
|
return { Empty {} };
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
Optional<Errno&> error() const
|
Optional<Errno const&> error() const
|
||||||
{
|
{
|
||||||
if (tag == 1)
|
if (tag == 1)
|
||||||
return *bit_cast<Errno*>(&error_bits[0]);
|
return m_error;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
bool is_error() const { return tag == 1; }
|
bool is_error() const { return tag == 1; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
alignas(Errno) u8 error_bits[sizeof(Errno)];
|
Errno m_error;
|
||||||
LittleEndian<Tag> tag;
|
LittleEndian<Tag> tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue