aboutsummaryrefslogtreecommitdiff
path: root/boot/result.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-08-05 01:03:55 +0200
committerEugen Wissner <belka@caraus.de>2026-08-05 21:27:36 +0200
commitb2dee14873402ee3d13d59ae5579593796ea862f (patch)
tree1f245eac1a23a73f45124498fc8274874e35750e /boot/result.cc
parent1c2fb173ea3b674207badc721556ad72962b266e (diff)
downloadelna-b2dee14873402ee3d13d59ae5579593796ea862f.tar.gz
Check that constants are initialized
Diffstat (limited to 'boot/result.cc')
-rw-r--r--boot/result.cc40
1 files changed, 27 insertions, 13 deletions
diff --git a/boot/result.cc b/boot/result.cc
index c47be95..e9090de 100644
--- a/boot/result.cc
+++ b/boot/result.cc
@@ -17,6 +17,7 @@ along with GCC; see the file COPYING3. If not see
#include "elna/boot/result.h"
+#include <algorithm>
#include <cstring>
#include <numeric>
@@ -87,6 +88,11 @@ namespace elna::boot
return this->m_name;
}
+ std::string identifier::to_string() const
+ {
+ return name();
+ }
+
const source_position& identifier::position() const
{
return this->m_position;
@@ -123,6 +129,17 @@ namespace elna::boot
return this->m_exported;
}
+ std::vector<identifier> extract_identifiers(const std::vector<identifier_definition>& identifiers)
+ {
+ std::vector<identifier> result;
+ result.reserve(identifiers.size());
+
+ std::ranges::transform(identifiers, std::back_inserter(result),
+ [](const auto& identifier) { return identifier.id(); });
+
+ return result;
+ }
+
integer_literal::integer_literal(bool is_signed, std::size_t size)
: m_signed(is_signed), m_size(size)
{
@@ -313,10 +330,6 @@ namespace elna::boot
std::optional<std::ptrdiff_t> integer_literal::to_signed() const
{
- if (!is_signed())
- {
- return std::nullopt;
- }
if (is_negative_minimum(sizeof(std::ptrdiff_t) * CHAR_BIT))
{
return std::numeric_limits<ptrdiff_t>::min();
@@ -327,15 +340,11 @@ namespace elna::boot
{
return std::nullopt;
}
- return mpz_sgn(this->raw) < 0 ? -rop : rop;
+ return is_negative() ? -rop : rop;
}
std::optional<std::size_t> integer_literal::to_unsigned() const
{
- if (is_signed())
- {
- return std::nullopt;
- }
auto [written, rop] = export_to_words<std::size_t>();
return written > 1 ? std::nullopt : std::make_optional(rop);
@@ -384,11 +393,11 @@ namespace elna::boot
{
std::size_t required_bits = mpz_sizeinbase(this->raw, 2);
- if (!is_negative_minimum(bits))
+ if (!is_negative() || !is_negative_minimum(bits))
{
++required_bits; // Add one bit for the sign.
}
- return required_bits <= bits && (mpz_sgn(this->raw) >= 0 || is_signed());
+ return required_bits <= bits && (!is_negative() || is_signed());
}
std::optional<integer_literal> integer_literal::check() &&
@@ -398,12 +407,12 @@ namespace elna::boot
bool integer_literal::is_negative_minimum(const std::size_t bits) const
{
- return mpz_sgn(this->raw) < 0 && mpz_scan1(this->raw, 0) == bits - 1;
+ return mpz_scan1(this->raw, 0) == bits - 1;
}
bool integer_literal::is_negative_minimum() const
{
- return is_negative_minimum(bits());
+ return is_negative() && is_negative_minimum(bits());
}
std::size_t integer_literal::bits() const
@@ -411,6 +420,11 @@ namespace elna::boot
return size() * CHAR_BIT;
}
+ bool integer_literal::is_negative() const
+ {
+ return mpz_sgn(this->raw) < 0;
+ }
+
std::size_t constant_value_hash::operator()(const elna::boot::constant_value& value) const noexcept
{
return std::visit([](auto&& alternative) -> std::size_t {