From b3a7a5731285625aa9fc6a347841591757860edb Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Tue, 1 Sep 2026 01:55:44 +0200 Subject: Fix const extern variable declarations --- boot/name_analysis.cc | 2 +- boot/type_check.cc | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'boot') diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index 70b9031..3c4c6f8 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -420,7 +420,7 @@ namespace elna::boot non_constant_expression_error::initializer{ extract_identifiers(declaration->identifiers) }); } } - else if (resolve_aliases(variable_type).get() != nullptr) + else if (!declaration->is_extern && resolve_aliases(variable_type).get() != nullptr) { auto position_span = source_position(declaration->identifiers.front().id().position().start(), declaration->identifiers.back().id().position().end()); diff --git a/boot/type_check.cc b/boot/type_check.cc index 068d958..74c8176 100644 --- a/boot/type_check.cc +++ b/boot/type_check.cc @@ -513,12 +513,40 @@ namespace elna::boot return verdict::pass; } + assign_check::verdict assign_check::check_array_conversion() const + { + auto assignee_array = ctx.resolved_assignee.get(); + auto assignment_array = ctx.resolved_assignment.get(); + + if (assignee_array == nullptr || assignment_array == nullptr + || assignee_array->size != assignment_array->size) + { + return verdict::pass; + } + auto assignee_element_const = resolve_aliases(assignee_array->base).get(); + auto assignment_element_const = resolve_aliases(assignment_array->base).get(); + + // An array is copied by value, so const can be added to the element type, + // but not removed. Writing to such an array is rejected on the lvalue. + if (assignee_element_const != nullptr + && assignee_element_const->unqualified == assignment_array->base) + { + return verdict::accept; + } + if (assignment_element_const != nullptr && assignee_element_const == nullptr) + { + return verdict::reject; + } + return verdict::pass; + } + bool assign_check::run() { auto const assign_handlers = { &assign_check::guard_const_laundering, &assign_check::check_exact_match, &assign_check::check_slice_conversion, + &assign_check::check_array_conversion, &assign_check::check_pointer_hatch, &assign_check::check_pointer_conversion }; -- cgit v1.2.3