diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index 3880ce25d2..9284ca6c97 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -698,8 +698,7 @@ static inline ASR::symbol_t *get_asr_owner(const ASR::expr_t *expr) { return ASRUtils::get_asr_owner(ASR::down_cast(expr)->m_name); } default: { - throw LCompilersException("Cannot find the ASR owner of underlying symbol of expression " - + std::to_string(expr->type)); + return nullptr; } } return nullptr; diff --git a/src/libasr/pass/array_op.cpp b/src/libasr/pass/array_op.cpp index d0c1ef5970..ddc20801f5 100644 --- a/src/libasr/pass/array_op.cpp +++ b/src/libasr/pass/array_op.cpp @@ -1460,47 +1460,39 @@ class ArrayOpVisitor : public ASR::CallReplacerOnExpressionsVisitor(*x.m_target) && - ASRUtils::is_array(ASRUtils::expr_type(x.m_value)) && - ASRUtils::is_array(ASRUtils::expr_type(x.m_target)) && - !ASR::is_a(*x.m_value)); if( (ASR::is_a(*ASRUtils::expr_type(x.m_target)) && ASR::is_a(*x.m_value)) || - (ASR::is_a(*x.m_value)) || - is_target_struct_member_array_and_value_array) { // TODO: fix for StructInstanceMember targets - if( is_target_struct_member_array_and_value_array ) { - if (realloc_lhs && ASRUtils::is_allocatable(x.m_target)) { // Add realloc-lhs later - Vec vec_alloc; - vec_alloc.reserve(al, 1); - ASR::alloc_arg_t alloc_arg; - alloc_arg.m_len_expr = nullptr; - alloc_arg.m_type = nullptr; - alloc_arg.loc = x.m_target->base.loc; - alloc_arg.m_a = x.m_target; - - - ASR::dimension_t* m_dims = nullptr; - size_t n_dims = ASRUtils::extract_dimensions_from_ttype( - ASRUtils::expr_type(x.m_value), m_dims); - Vec vec_dims; - vec_dims.reserve(al, n_dims); - for( size_t i = 0; i < n_dims; i++ ) { - ASR::dimension_t dim; - dim.loc = x.m_value->base.loc; - dim.m_start = PassUtils::get_bound(x.m_value, i + 1, "lbound", al); - dim.m_length = ASRUtils::get_size(x.m_value, i + 1, al); - vec_dims.push_back(al, dim); - } + (ASR::is_a(*x.m_value)) ) { + if( realloc_lhs && ASRUtils::is_allocatable(x.m_target)) { // Add realloc-lhs later + Vec vec_alloc; + vec_alloc.reserve(al, 1); + ASR::alloc_arg_t alloc_arg; + alloc_arg.m_len_expr = nullptr; + alloc_arg.m_type = nullptr; + alloc_arg.loc = x.m_target->base.loc; + alloc_arg.m_a = x.m_target; + + + ASR::dimension_t* m_dims = nullptr; + size_t n_dims = ASRUtils::extract_dimensions_from_ttype( + ASRUtils::expr_type(x.m_value), m_dims); + Vec vec_dims; + vec_dims.reserve(al, n_dims); + for( size_t i = 0; i < n_dims; i++ ) { + ASR::dimension_t dim; + dim.loc = x.m_value->base.loc; + dim.m_start = PassUtils::get_bound(x.m_value, i + 1, "lbound", al); + dim.m_length = ASRUtils::get_size(x.m_value, i + 1, al); + vec_dims.push_back(al, dim); + } - alloc_arg.m_dims = vec_dims.p; - alloc_arg.n_dims = vec_dims.n; - vec_alloc.push_back(al, alloc_arg); - pass_result.push_back(al, ASRUtils::STMT(ASR::make_Allocate_t( - al, x.base.base.loc, vec_alloc.p, 1, nullptr, nullptr, nullptr))); - remove_original_statement = false; - } + alloc_arg.m_dims = vec_dims.p; + alloc_arg.n_dims = vec_dims.n; + vec_alloc.push_back(al, alloc_arg); + pass_result.push_back(al, ASRUtils::STMT(ASR::make_Allocate_t( + al, x.base.base.loc, vec_alloc.p, 1, nullptr, nullptr, nullptr))); + remove_original_statement = false; } return ; } diff --git a/src/libasr/pass/pass_utils.cpp b/src/libasr/pass/pass_utils.cpp index 50169d9093..18fa18c1e4 100644 --- a/src/libasr/pass/pass_utils.cpp +++ b/src/libasr/pass/pass_utils.cpp @@ -560,7 +560,25 @@ namespace LCompilers { ASR::expr_t* get_bound(ASR::expr_t* arr_expr, int dim, std::string bound, Allocator& al) { + ASR::ttype_t* x_mv_type = ASRUtils::expr_type(arr_expr); + ASR::dimension_t* m_dims; + int n_dims = ASRUtils::extract_dimensions_from_ttype(x_mv_type, m_dims); + bool is_data_only_array = ASRUtils::is_fixed_size_array(m_dims, n_dims) && ASRUtils::get_asr_owner(arr_expr) && + ASR::is_a(*ASRUtils::get_asr_owner(arr_expr)); ASR::ttype_t* int32_type = ASRUtils::TYPE(ASR::make_Integer_t(al, arr_expr->base.loc, 4)); + if (is_data_only_array) { + const Location& loc = arr_expr->base.loc; + ASR::expr_t* zero = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 0, int32_type)); + ASR::expr_t* one = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 1, int32_type)); + if( bound == "ubound" ) { + return ASRUtils::EXPR(ASR::make_IntegerBinOp_t( + al, arr_expr->base.loc, m_dims[dim - 1].m_length, ASR::binopType::Sub, one, int32_type, nullptr)); + } + if ( m_dims[dim - 1].m_start != nullptr ) { + return m_dims[dim - 1].m_start; + } + return zero; + } ASR::expr_t* dim_expr = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, arr_expr->base.loc, dim, int32_type)); ASR::arrayboundType bound_type = ASR::arrayboundType::LBound; if( bound == "ubound" ) { diff --git a/src/libasr/pass/subroutine_from_function.cpp b/src/libasr/pass/subroutine_from_function.cpp index 920b9fdc26..eff6493a06 100644 --- a/src/libasr/pass/subroutine_from_function.cpp +++ b/src/libasr/pass/subroutine_from_function.cpp @@ -318,15 +318,9 @@ class ReplaceFunctionCallWithSubroutineCallVisitor: } void visit_Assignment(const ASR::Assignment_t &x) { - bool is_target_struct_member_array_and_value_array = - (ASR::is_a(*x.m_target) && - ASRUtils::is_array(ASRUtils::expr_type(x.m_value)) && - ASRUtils::is_array(ASRUtils::expr_type(x.m_target)) && - !ASR::is_a(*x.m_value)); if( (ASR::is_a(*ASRUtils::expr_type(x.m_target)) && ASR::is_a(*x.m_value)) || - (ASR::is_a(*x.m_value)) || - is_target_struct_member_array_and_value_array) { // TODO: fix for StructInstanceMember targets + (ASR::is_a(*x.m_value))) { return ; }