diff options
Diffstat (limited to 'boot/type_check.cc')
| -rw-r--r-- | boot/type_check.cc | 28 |
1 files changed, 28 insertions, 0 deletions
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<array_type>(); + auto assignment_array = ctx.resolved_assignment.get<array_type>(); + + 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<constant_type>(); + auto assignment_element_const = resolve_aliases(assignment_array->base).get<constant_type>(); + + // 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 }; |
