aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-08-01 16:05:51 +0200
committerEugen Wissner <belka@caraus.de>2026-08-01 16:05:51 +0200
commit71b3bbb7698b13b42c99a4ca66c27db4a6189ff8 (patch)
tree1fc6ed246ecc0cf561f38ad774a4815ba357ea7b /include
parent8539c10542a4be1e1127daea60bf1b1e4c37e092 (diff)
downloadelna-71b3bbb7698b13b42c99a4ca66c27db4a6189ff8.tar.gz
Enforce integral values in slice ranges
Diffstat (limited to 'include')
-rw-r--r--include/elna/boot/result.h28
-rw-r--r--include/elna/boot/type_check.h15
2 files changed, 31 insertions, 12 deletions
diff --git a/include/elna/boot/result.h b/include/elna/boot/result.h
index 4c6046d..56884ff 100644
--- a/include/elna/boot/result.h
+++ b/include/elna/boot/result.h
@@ -268,17 +268,7 @@ namespace elna::boot
bool is_signed() const;
std::size_t size() const;
-
- template<typename T>
- T to() const
- requires is_integral<T>
- {
- T result{};
-
- mpz_export(&result, nullptr, 1, sizeof(T), 0, 0, this->raw);
-
- return result;
- }
+ std::string to_string(const std::uint8_t base = 10U) const;
/**
* Exports the stored value as a host \c std::ptrdiff_t.
@@ -294,6 +284,21 @@ namespace elna::boot
*/
std::optional<std::size_t> to_unsigned() const;
+ /**
+ * Attempts to narrow this literal's internally stored size to
+ * \p target_size bytes, in place.
+ *
+ * If the current value can be represented within \p target_size bytes
+ * (given the literal's existing signedness), the internal storage size
+ * is updated to \p target_size and the function returns \c true. If the
+ * value would not fit, the literal is left unmodified and \c false is
+ * returned.
+ *
+ * \param target_size Size of the target type in bytes.
+ * \return Whether the value fits and has been changed.
+ */
+ bool fit_into(const std::size_t target_size);
+
template<typename T>
static integer_literal from(T initial)
requires is_integral<T>
@@ -313,6 +318,7 @@ namespace elna::boot
mpz_t raw;
integer_literal(bool is_signed, std::size_t size);
+ bool fits_in(const std::size_t bits) const;
std::optional<integer_literal> check() &&;
bool is_negative_minimum(const std::size_t bits) const;
bool is_negative_minimum() const;
diff --git a/include/elna/boot/type_check.h b/include/elna/boot/type_check.h
index 628af06..82f0092 100644
--- a/include/elna/boot/type_check.h
+++ b/include/elna/boot/type_check.h
@@ -54,6 +54,10 @@ namespace elna::boot
{
type target;
};
+ struct integer_literal_overflow
+ {
+ integer_literal overflow;
+ };
enum class kind {
record_base,
for_range,
@@ -63,7 +67,15 @@ namespace elna::boot
non_indexable,
dereference_of_non_pointer
};
- using payload_type = std::variant<expected_type, return_type, unary, binary, invalid_cast, kind>;
+ using payload_type = std::variant<
+ expected_type,
+ return_type,
+ unary,
+ binary,
+ invalid_cast,
+ integer_literal_overflow,
+ kind
+ >;
type_mismatch_error(const source_position position,
type actual, payload_type payload);
@@ -213,5 +225,6 @@ namespace elna::boot
void visit(cast_expression *expression) override;
void visit(unary_expression *expression) override;
void visit(binary_expression *expression) override;
+ void visit(literal<integer_literal> *expression) override;
};
}