diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-08-14 23:14:38 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-08-14 23:14:38 +0200 |
| commit | 33ae72a3c73f6219be86715e8da71ed345f6077c (patch) | |
| tree | 1c6c98be816508e9231fa1ada3f79ec940ab1cf1 | |
| parent | d696abc97143061bf2abb05922188e12b59306c1 (diff) | |
| download | elna-33ae72a3c73f6219be86715e8da71ed345f6077c.tar.gz | |
Map Int and Word to hardware word sizes
| -rw-r--r-- | boot/dependency.cc | 4 | ||||
| -rw-r--r-- | boot/driver.cc | 2 | ||||
| -rw-r--r-- | boot/evaluator.cc | 2 | ||||
| -rw-r--r-- | boot/materialization.cc | 20 | ||||
| -rw-r--r-- | boot/name_analysis.cc | 6 | ||||
| -rw-r--r-- | boot/result.cc | 6 | ||||
| -rw-r--r-- | boot/type_check.cc | 32 | ||||
| -rw-r--r-- | boot/validation.cc | 2 | ||||
| -rw-r--r-- | gcc/gcc/elna-diagnostic.cc | 2 | ||||
| -rw-r--r-- | gcc/gcc/elna-generic.cc | 7 | ||||
| -rw-r--r-- | gcc/gcc/elna-tree.cc | 4 | ||||
| -rw-r--r-- | include/elna/boot/dependency.h | 6 | ||||
| -rw-r--r-- | include/elna/boot/driver.h | 4 | ||||
| -rw-r--r-- | include/elna/boot/evaluator.h | 2 | ||||
| -rw-r--r-- | include/elna/boot/materialization.h | 4 | ||||
| -rw-r--r-- | include/elna/boot/name_analysis.h | 10 | ||||
| -rw-r--r-- | include/elna/boot/result.h | 16 | ||||
| -rw-r--r-- | include/elna/boot/type_check.h | 18 | ||||
| -rw-r--r-- | include/elna/boot/validation.h | 4 | ||||
| -rw-r--r-- | include/elna/gcc/elna-diagnostic.h | 2 | ||||
| -rw-r--r-- | testsuite/fail_compilation/case_label_overflow.elna | 11 |
21 files changed, 84 insertions, 80 deletions
diff --git a/boot/dependency.cc b/boot/dependency.cc index bd1251a..4590513 100644 --- a/boot/dependency.cc +++ b/boot/dependency.cc @@ -62,7 +62,7 @@ namespace elna::boot return outcome; } - error_list analyze_semantics(std::unique_ptr<unit>& tree, symbol_bag& bag, + diagnostic_list analyze_semantics(std::unique_ptr<unit>& tree, symbol_bag& bag, const target_info& target) { name_analysis_visitor name_analyser(bag, target); @@ -86,7 +86,7 @@ namespace elna::boot { return std::move(validator.errors()); } - return error_list{}; + return diagnostic_list{}; } std::filesystem::path build_path(const std::vector<std::string>& segments) diff --git a/boot/driver.cc b/boot/driver.cc index 24a11fa..3607995 100644 --- a/boot/driver.cc +++ b/boot/driver.cc @@ -30,7 +30,7 @@ namespace elna::boot } syntax_error::syntax_error(const std::string& message, const yy::location& location) - : error(make_position(location)), message(message) + : diagnostic(make_position(location)), message(message) { } diff --git a/boot/evaluator.cc b/boot/evaluator.cc index 07b2953..b37d1fa 100644 --- a/boot/evaluator.cc +++ b/boot/evaluator.cc @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { non_constant_expression_error::non_constant_expression_error(const source_position position, payload_type payload) - : error(position), payload(std::move(payload)) + : diagnostic(position), payload(std::move(payload)) { } diff --git a/boot/materialization.cc b/boot/materialization.cc index e055dfd..8c436b3 100644 --- a/boot/materialization.cc +++ b/boot/materialization.cc @@ -20,7 +20,7 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { materialization_error::materialization_error(const source_position position) - : error(position) + : diagnostic(position) { } @@ -43,6 +43,11 @@ namespace elna::boot if (auto negated_literal = literal->value.negate()) { literal->value = negated_literal.value(); + if (!literal->has_explicit_size + && !literal->value.fit_into(true, target.int_properties.front().size)) + { + add_error<materialization_error>(literal->position()); + } } else { @@ -50,12 +55,23 @@ namespace elna::boot } break; case unmarked: - if (!literal->value.fit_into(true, literal->value.size())) + { + const auto target_size = literal->has_explicit_size + ? literal->value.size() + : target.int_properties.front().size; + + if (!literal->value.fit_into(true, target_size)) { add_error<materialization_error>(literal->position()); } break; + } case _unsigned: + if (!literal->has_explicit_size + && !literal->value.fit_into(false, target.word_properties.front().size)) + { + add_error<materialization_error>(literal->position()); + } break; } } diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index 4127466..0889ef9 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { declaration_error::declaration_error(const source_position position, const std::string& name, payload_type payload) - : error(position), name(name), payload(payload) + : diagnostic(position), name(name), payload(payload) { } @@ -70,7 +70,7 @@ namespace elna::boot } const_qualifier_error::const_qualifier_error(const source_position position, payload_type payload) - : error(position), payload(std::move(payload)) + : diagnostic(position), payload(std::move(payload)) { } @@ -113,7 +113,7 @@ namespace elna::boot member_error::member_error(const source_position position, const std::string& name, const type& composite, payload_type payload) - : error(position), name(name), composite(composite), payload(std::move(payload)) + : diagnostic(position), name(name), composite(composite), payload(std::move(payload)) { } diff --git a/boot/result.cc b/boot/result.cc index a5f0803..3970b1f 100644 --- a/boot/result.cc +++ b/boot/result.cc @@ -63,17 +63,17 @@ namespace elna::boot return this->m_start != this->m_end; } - error::error(const source_position position) + diagnostic::diagnostic(const source_position position) : position(position) { } - std::deque<std::unique_ptr<error>>& error_container::errors() + std::deque<std::unique_ptr<diagnostic>>& diagnostic_container::errors() { return m_errors; } - bool error_container::has_errors() const + bool diagnostic_container::has_errors() const { return !m_errors.empty(); } diff --git a/boot/type_check.cc b/boot/type_check.cc index 07e563f..e58a50e 100644 --- a/boot/type_check.cc +++ b/boot/type_check.cc @@ -90,7 +90,7 @@ namespace elna::boot trait_error::trait_error(const source_position position, const std::string& trait_name, payload_type payload) - : error(position), trait_name(trait_name), payload(std::move(payload)) + : diagnostic(position), trait_name(trait_name), payload(std::move(payload)) { } @@ -115,7 +115,7 @@ namespace elna::boot type_mismatch_error::type_mismatch_error(const source_position position, type actual, payload_type payload) - : error(position), actual(std::move(actual)), payload(std::move(payload)) + : diagnostic(position), actual(std::move(actual)), payload(std::move(payload)) { } @@ -158,11 +158,6 @@ namespace elna::boot return "Type '" + this->actual.to_string() + "' cannot be converted to '" + payload.target.to_string() + "'"; } - else if constexpr (std::is_same_v<T, integer_literal_overflow>) - { - return "The number " + payload.overflow.to_string() - + " does not fit into the type '" + actual.to_string() + "'"; - } else if constexpr (std::is_same_v<T, constant_assignment>) { return "Cannot assign to a value of type '" + this->actual.to_string() @@ -173,7 +168,7 @@ namespace elna::boot type_requirement_error::type_requirement_error(const source_position position, type actual, kind kind) - : error(position), actual(std::move(actual)), m_kind(kind) + : diagnostic(position), actual(std::move(actual)), m_kind(kind) { } @@ -207,7 +202,7 @@ namespace elna::boot cyclic_declaration_error::cyclic_declaration_error(const source_position position, const std::vector<std::string>& cycle) - : error(position), cycle(cycle) + : diagnostic(position), cycle(cycle) { } @@ -226,7 +221,7 @@ namespace elna::boot argument_count_error::argument_count_error(const source_position position, kind kind, std::string applicand, std::size_t expected, std::size_t actual) - : error(position), m_kind(kind), applicand(std::move(applicand)), expected(expected), actual(actual) + : diagnostic(position), m_kind(kind), applicand(std::move(applicand)), expected(expected), actual(actual) { } @@ -1059,21 +1054,4 @@ namespace elna::boot } } - void type_analysis_visitor::visit(literal<integer_literal> *expression) - { - bool narrowed{ false }; - if (expression->value.is_signed()) - { - narrowed = expression->value.fit_into(target.int_properties.front().size); - } - else - { - narrowed = expression->value.fit_into(target.word_properties.front().size); - } - if (!narrowed) - { - add_error<type_mismatch_error>(expression->position(), expression->type_decoration, - type_mismatch_error::integer_literal_overflow{ expression->value }); - } - } } diff --git a/boot/validation.cc b/boot/validation.cc index 26d4f64..a81282b 100644 --- a/boot/validation.cc +++ b/boot/validation.cc @@ -22,7 +22,7 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { validation_error::validation_error(const source_position position, source_position first) - : error(position), first(first) + : diagnostic(position), first(first) { } diff --git a/gcc/gcc/elna-diagnostic.cc b/gcc/gcc/elna-diagnostic.cc index 3bc274e..ea1f64c 100644 --- a/gcc/gcc/elna-diagnostic.cc +++ b/gcc/gcc/elna-diagnostic.cc @@ -63,7 +63,7 @@ namespace elna::gcc return make_location(caret, start, end); } - void report_errors(const std::deque<std::unique_ptr<boot::error>>& errors) + void report_errors(const std::deque<std::unique_ptr<boot::diagnostic>>& errors) { for (const auto& error : errors) { diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc index aff5d9d..5230196 100644 --- a/gcc/gcc/elna-generic.cc +++ b/gcc/gcc/elna-generic.cc @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "cgraph.h" #include "gimplify.h" +#include "dumpfile.h" #include "stringpool.h" #include "realmpfr.h" #include "fold-const.h" @@ -475,6 +476,8 @@ namespace elna::gcc DECL_PRESERVE_P(fndecl) = 1; + dump_function(TDI_original, fndecl); + pop_cfun(); gimplify_function_tree(fndecl); cgraph_node::finalize_function(fndecl, true); @@ -482,7 +485,9 @@ namespace elna::gcc void generic_visitor::visit(boot::literal<boot::integer_literal> *literal) { - this->current_expression = constant_to_tree(boot::constant_value{ literal->value }, this->symbols); + tree literal_type = get_inner_alias(literal->type_decoration, this->symbols); + this->current_expression = constant_to_tree(boot::constant_value{ literal->value }, + this->symbols, literal_type); } void generic_visitor::visit(boot::literal<double> *literal) diff --git a/gcc/gcc/elna-tree.cc b/gcc/gcc/elna-tree.cc index 688fc4a..255cf60 100644 --- a/gcc/gcc/elna-tree.cc +++ b/gcc/gcc/elna-tree.cc @@ -259,7 +259,7 @@ namespace elna::gcc { if (auto converted = literal_value.try_to<std::ptrdiff_t>()) { - return build_int_cst(elna_int_type_node, *converted); + return build_int_cst(type, *converted); } return NULL_TREE; } @@ -267,7 +267,7 @@ namespace elna::gcc { if (auto converted = literal_value.try_to<std::size_t>()) { - return build_int_cstu(elna_word_type_node, *converted); + return build_int_cstu(type, *converted); } return NULL_TREE; } diff --git a/include/elna/boot/dependency.h b/include/elna/boot/dependency.h index 854c661..75bbed3 100644 --- a/include/elna/boot/dependency.h +++ b/include/elna/boot/dependency.h @@ -26,9 +26,9 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { - class dependency : public error_container + class dependency : public diagnostic_container { - error_list m_errors; + diagnostic_list m_errors; public: std::unique_ptr<unit> tree; @@ -39,7 +39,7 @@ namespace elna::boot dependency read_source(std::istream& entry_point, const target_info& target); std::filesystem::path build_path(const std::vector<std::string>& segments); - error_list analyze_semantics(std::unique_ptr<unit>& tree, symbol_bag& bag, + diagnostic_list analyze_semantics(std::unique_ptr<unit>& tree, symbol_bag& bag, const target_info& target); template<typename T> diff --git a/include/elna/boot/driver.h b/include/elna/boot/driver.h index 2503e39..9076e23 100644 --- a/include/elna/boot/driver.h +++ b/include/elna/boot/driver.h @@ -25,7 +25,7 @@ namespace elna::boot { source_position make_position(const yy::location& location); - class syntax_error final : public error + class syntax_error final : public diagnostic { std::string message; @@ -35,7 +35,7 @@ namespace elna::boot std::string what() const override; }; - class driver final : public error_container + class driver final : public diagnostic_container { public: std::unique_ptr<unit> tree; diff --git a/include/elna/boot/evaluator.h b/include/elna/boot/evaluator.h index 02db6ab..dd70483 100644 --- a/include/elna/boot/evaluator.h +++ b/include/elna/boot/evaluator.h @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { - class non_constant_expression_error final : public error + class non_constant_expression_error final : public diagnostic { public: struct initializer diff --git a/include/elna/boot/materialization.h b/include/elna/boot/materialization.h index 21a217d..2c571c5 100644 --- a/include/elna/boot/materialization.h +++ b/include/elna/boot/materialization.h @@ -21,7 +21,7 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { - class materialization_error final : public error + class materialization_error final : public diagnostic { public: materialization_error(const source_position position); @@ -29,7 +29,7 @@ namespace elna::boot std::string what() const override; }; - class materialization_visitor final : public walking_visitor, public error_container + class materialization_visitor final : public walking_visitor, public diagnostic_container { const target_info& target; diff --git a/include/elna/boot/name_analysis.h b/include/elna/boot/name_analysis.h index a9e7f24..736874a 100644 --- a/include/elna/boot/name_analysis.h +++ b/include/elna/boot/name_analysis.h @@ -33,7 +33,7 @@ namespace elna::boot * Error declaring or using a symbol (undeclared, redefinition, * local export). */ - class declaration_error final : public error + class declaration_error final : public diagnostic { public: enum class kind @@ -63,7 +63,7 @@ namespace elna::boot * \c const qualifier used incorrectly — wrong position or * duplicate. */ - class const_qualifier_error final : public error + class const_qualifier_error final : public diagnostic { public: enum class kind @@ -89,7 +89,7 @@ namespace elna::boot /** * Error accessing or defining a member of a record or enumeration. */ - class member_error final : public error + class member_error final : public diagnostic { public: enum class kind { not_found, field_on_type }; @@ -123,7 +123,7 @@ namespace elna::boot /** * Performs name analysis. */ - class name_analysis_visitor final : public walking_visitor, public error_container + class name_analysis_visitor final : public walking_visitor, public diagnostic_container { type current_type; symbol_bag bag; @@ -183,7 +183,7 @@ namespace elna::boot /** * Collects global declarations without resolving any symbols. */ - class declaration_visitor final : public empty_visitor, public error_container + class declaration_visitor final : public empty_visitor, public diagnostic_container { public: forward_table unresolved; diff --git a/include/elna/boot/result.h b/include/elna/boot/result.h index bf2149a..23505d0 100644 --- a/include/elna/boot/result.h +++ b/include/elna/boot/result.h @@ -81,13 +81,13 @@ namespace elna::boot /** * A compilation error consists of an error message and position. */ - class error + class diagnostic { protected: - error(const source_position position); + diagnostic(const source_position position); public: - virtual ~error() = default; + virtual ~diagnostic() = default; /// Error position. const source_position position; @@ -106,17 +106,17 @@ namespace elna::boot } }; - using error_list = std::deque<std::unique_ptr<error>>; + using diagnostic_list = std::deque<std::unique_ptr<diagnostic>>; - class error_container + class diagnostic_container { protected: - error_list m_errors; + diagnostic_list m_errors; - error_container() = default; + diagnostic_container() = default; public: - error_list& errors(); + diagnostic_list& errors(); template<typename T, typename... Args> void add_error(Args&&... arguments) diff --git a/include/elna/boot/type_check.h b/include/elna/boot/type_check.h index 52eec61..7a8eece 100644 --- a/include/elna/boot/type_check.h +++ b/include/elna/boot/type_check.h @@ -30,7 +30,7 @@ namespace elna::boot /** * Expected type does not match the actual type of an expression. */ - class type_mismatch_error final : public error + class type_mismatch_error final : public diagnostic { public: struct expected_type @@ -54,10 +54,6 @@ namespace elna::boot { type target; }; - struct integer_literal_overflow - { - integer_literal overflow; - }; struct constant_assignment { }; @@ -67,7 +63,6 @@ namespace elna::boot unary, binary, invalid_cast, - integer_literal_overflow, constant_assignment >; @@ -81,7 +76,7 @@ namespace elna::boot payload_type payload; }; - class type_requirement_error : public error + class type_requirement_error : public diagnostic { public: enum class kind @@ -107,7 +102,7 @@ namespace elna::boot /** * Cyclic type declaration. */ - class cyclic_declaration_error final : public error + class cyclic_declaration_error final : public diagnostic { std::vector<std::string> cycle; @@ -121,7 +116,7 @@ namespace elna::boot * Argument count in a procedure call or array constructor doesn't match * the expected number of parameters or elements. */ - class argument_count_error final : public error + class argument_count_error final : public diagnostic { public: enum class kind @@ -146,7 +141,7 @@ namespace elna::boot /** * A trait invocation is invalid. */ - class trait_error final : public error + class trait_error final : public diagnostic { public: struct offset_not_field_name @@ -208,7 +203,7 @@ namespace elna::boot * procedure argument counts, record field validity, * and type declaration well-formedness. */ - class type_analysis_visitor final : public walking_visitor, public error_container + class type_analysis_visitor final : public walking_visitor, public diagnostic_container { symbol_bag bag; std::shared_ptr<procedure_info> current_procedure; @@ -249,6 +244,5 @@ 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; }; } diff --git a/include/elna/boot/validation.h b/include/elna/boot/validation.h index 65972b7..2b1de95 100644 --- a/include/elna/boot/validation.h +++ b/include/elna/boot/validation.h @@ -27,7 +27,7 @@ namespace elna::boot /** * Validation error. */ - class validation_error final : public error + class validation_error final : public diagnostic { public: validation_error(const source_position position, source_position first); @@ -43,7 +43,7 @@ namespace elna::boot * Validates: * - case label uniqueness */ - class validation_visitor final : public empty_visitor, public error_container + class validation_visitor final : public empty_visitor, public diagnostic_container { symbol_bag& bag; evaluator constant_evaluator; diff --git a/include/elna/gcc/elna-diagnostic.h b/include/elna/gcc/elna-diagnostic.h index 3e0dd51..10d5b44 100644 --- a/include/elna/gcc/elna-diagnostic.h +++ b/include/elna/gcc/elna-diagnostic.h @@ -43,5 +43,5 @@ namespace elna::gcc location_t get_location(const boot::source_position *position); location_t make_range(const boot::source_position& position); - void report_errors(const std::deque<std::unique_ptr<boot::error>>& errors); + void report_errors(const std::deque<std::unique_ptr<boot::diagnostic>>& errors); } diff --git a/testsuite/fail_compilation/case_label_overflow.elna b/testsuite/fail_compilation/case_label_overflow.elna new file mode 100644 index 0000000..ab6dbfd --- /dev/null +++ b/testsuite/fail_compilation/case_label_overflow.elna @@ -0,0 +1,11 @@ +var + x: Int8 := 100i8 + +begin + case x of + 100i8: assert(true) + | 100i8 + 100i8: assert(false) (* @Error Case label must be a constant expression *) + else + assert(false) + end +end. |
