From 56a1244380133ab400f98d2da15353e080ffb360 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Thu, 15 Oct 2026 14:46:38 +0200 Subject: Restrict index types to Int and Word --- boot/name_analysis.cc | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) (limited to 'boot/name_analysis.cc') diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index 36faee1..9305cd2 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -144,6 +144,11 @@ namespace elna::boot { return "All constants should be initialized"; } + else if constexpr (std::is_same_v) + { + return "Array dimension must be of type 'Word' or 'Int', but got '" + + payload.actual.to_string() + "'"; + } else if constexpr (std::is_same_v) { switch (payload) @@ -162,6 +167,8 @@ namespace elna::boot case enumeration_values: return "Enumeration values should be omitted, given for the first member only," " or given for all members"; + case array_dimension_size: + return "Array dimension must be greater than zero"; default: __builtin_unreachable(); } @@ -327,7 +334,7 @@ namespace elna::boot resolving_visitor::resolving_visitor(symbol_bag& bag, const target_info& target, const std::filesystem::path& module_path) - : bag(bag), constant_evaluator(this->bag, target), module_file(module_path) + : bag(bag), target(target), constant_evaluator(this->bag, target), module_file(module_path) { } @@ -580,15 +587,52 @@ namespace elna::boot this->current_type = type(); return; } - const auto size_constant = this->constant_evaluator.evaluate_index(expression->dimensions()); - if (!size_constant.has_value()) + if (!is_index_type(expression->dimensions().type_decoration, this->target)) + { + add_error(expression->dimensions().position(), + declaration_format_error::array_dimension_type{ expression->dimensions().type_decoration }); + this->current_type = type(); + return; + } + + const std::optional evaluated = + this->constant_evaluator.evaluate(expression->dimensions()); + + if (!evaluated.has_value()) + { + add_error(expression->position(), + non_constant_expression_error::array_dimensions{ array_base }); + this->current_type = type(); + return; + } + + const auto *literal = std::get_if(&evaluated.value()); + + if (literal == nullptr) { add_error(expression->position(), non_constant_expression_error::array_dimensions{ array_base }); this->current_type = type(); return; } + if (*literal <= 0) + { + add_error(expression->dimensions().position(), + declaration_format_error::kind::array_dimension_size); + this->current_type = type(); + return; + } + + const std::optional size_constant = literal->try_to(); + + if (!size_constant.has_value()) + { + add_error(expression->dimensions().position(), + declaration_format_error::kind::array_dimension_size); + this->current_type = type(); + return; + } this->current_type = type(std::make_shared(array_base, size_constant.value())); } -- cgit v1.2.3