| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- // SPDX-License-Identifier: Apache-2.0
- use super::vartable::Vartable;
- use crate::codegen::cfg::{ControlFlowGraph, Instr};
- use crate::codegen::Expression;
- use crate::sema::ast::Type;
- use solang_parser::pt::Loc;
- /// This function is called whenever an assignment statement of an array is encountered. We have to ensure
- /// that the variable number of the array is tied to the variable number of the correct temporary variable.
- /// We have two cases:
- /// Case 1: If the right hand side is an array, the left array keeps track of the temp variable of the right array (if a temp variable exists)
- /// Case 2: If reallocation of the left array is done (with a new expression), we create a new temp variable and the left side tracks it.
- /// If that's the case, we return an AllocDynamicArray expression with the size being the temp variable to avoid repetitive expressions in the cfg.
- pub(crate) fn handle_array_assign(
- right: Expression,
- cfg: &mut ControlFlowGraph,
- vartab: &mut Vartable,
- pos: &usize,
- ) -> Expression {
- if let Expression::AllocDynamicArray(loc, ty @ Type::Array(..), size, option) = right {
- // If we re-allocate the pointer, create a new temp variable to hold the new array length
- let temp_res = vartab.temp_name("array_length", &Type::Uint(32));
- cfg.add(
- vartab,
- Instr::Set {
- loc: Loc::Codegen,
- res: temp_res,
- expr: *size,
- },
- );
- cfg.array_lengths_temps.insert(*pos, temp_res);
- Expression::AllocDynamicArray(
- loc,
- ty,
- Box::new(Expression::Variable(Loc::Codegen, Type::Uint(32), temp_res)),
- option,
- )
- } else {
- if let Expression::Variable(_, _, right_res) = &right {
- // If we have initialized a temp var for this var
- if cfg.array_lengths_temps.contains_key(right_res) {
- let to_update = cfg.array_lengths_temps[right_res];
- cfg.array_lengths_temps.insert(*pos, to_update);
- } else {
- // If the right hand side doesn't have a temp, it must be a function parameter or a struct member.
- cfg.array_lengths_temps.remove(pos);
- }
- }
- right.clone()
- }
- }
|