ReAlloc

Reallocates objects to a new shape, allocating them if needed.

Declaration

Syntax

ReAlloc(alloc_arg* args, expr shape_differs)

Arguments

Argument

Описание

args

one alloc_arg, the object and its new shape.

shape_differs

a scalar logical, true when the allocated object has a shape other than the new one.

Return values

None.

Описание

ReAlloc exists for automatic reallocation on assignment: when the left hand side of an assignment is an allocatable whose shape does not match the right hand side, the object has to be deallocated and allocated again. Unlike Allocate, it is not an error for the object to be allocated already.

It is generated by the compiler rather than written by a user, and the realloc_lhs member of Assignment is what asks for it.

args has exactly one element. The object is allocated with the shape of args when it is not allocated, and reallocated when it is allocated and shape_differs is true (F2018 10.2.1.3), also when both shapes have the same number of elements, as in a = transpose(a). The pass that inserts the node decides when the shape differs and records it in shape_differs, which compares the extent of the object in each dimension (ArraySize) with the new length; for an object of rank 0 it is .false.. Since it reads the array descriptor, shape_differs is evaluated only while the object is allocated, and a code generator only evaluates it. A character object is also reallocated when its length differs from len_expr.

Examples

(ReAlloc
  :args [
    (alloc_arg
      :a (Var
        :v (SymbolRef 1 "a")
      )
      :dims [
        (dimension
          :start (IntegerConstant
            :n 1
            :type (Integer
              :kind 4
            )
            :intboz_type :Decimal
          )
          :length (IntegerConstant
            :n 20
            :type (Integer
              :kind 4
            )
            :intboz_type :Decimal
          )
        )
      ]
      :codims []
      :len_expr nil
      :sym_subclass nil
      :type nil
    )
  ]
  :shape_differs (IntegerCompare
    :left (ArraySize
      :v (Var
        :v (SymbolRef 1 "a")
      )
      :dim (IntegerConstant
        :n 1
        :type (Integer
          :kind 4
        )
        :intboz_type :Decimal
      )
      :type (Integer
        :kind 4
      )
      :value nil
    )
    :op :NotEq
    :right (IntegerConstant
      :n 20
      :type (Integer
        :kind 4
      )
      :intboz_type :Decimal
    )
    :type (Logical
      :kind 4
    )
    :value nil
  )
)

It comes from this complete ASR text document:

(TranslationUnit
  :symtab (SymbolTable
    :id 0
    :symbols {
      "main" (Program
        :symtab (SymbolTable
          :id 1
          :symbols {
            "a" (Variable
              :parent_symtab 1
              :name "a"
              :dependencies []
              :intent :Local
              :symbolic_value nil
              :value nil
              :storage :Default
              :type (Allocatable
                :type (Array
                  :type (Integer
                    :kind 4
                  )
                  :dims [
                    (dimension
                      :start nil
                      :length nil
                    )
                  ]
                  :physical_type :DescriptorArray
                  :memory_space :Global
                )
              )
              :type_declaration nil
              :abi :Source
              :access :Public
              :presence :Required
              :value_attr false
              :target_attr false
              :contiguous_attr false
              :bindc_name nil
              :is_volatile false
              :is_protected false
              :pass_attr :NotMethod
              :self_argument nil
              :codims []
              :common_block nil
            )
            "p" (Variable
              :parent_symtab 1
              :name "p"
              :dependencies []
              :intent :Local
              :symbolic_value nil
              :value nil
              :storage :Default
              :type (Pointer
                :type (Integer
                  :kind 4
                )
              )
              :type_declaration nil
              :abi :Source
              :access :Public
              :presence :Required
              :value_attr false
              :target_attr false
              :contiguous_attr false
              :bindc_name nil
              :is_volatile false
              :is_protected false
              :pass_attr :NotMethod
              :self_argument nil
              :codims []
              :common_block nil
            )
            "stat" (Variable
              :parent_symtab 1
              :name "stat"
              :dependencies []
              :intent :Local
              :symbolic_value nil
              :value nil
              :storage :Default
              :type (Integer
                :kind 4
              )
              :type_declaration nil
              :abi :Source
              :access :Public
              :presence :Required
              :value_attr false
              :target_attr false
              :contiguous_attr false
              :bindc_name nil
              :is_volatile false
              :is_protected false
              :pass_attr :NotMethod
              :self_argument nil
              :codims []
              :common_block nil
            )
          }
        )
        :name "main"
        :dependencies []
        :body [
          (Allocate
            :args [
              (alloc_arg
                :a (Var
                  :v (SymbolRef 1 "a")
                )
                :dims [
                  (dimension
                    :start (IntegerConstant
                      :n 1
                      :type (Integer
                        :kind 4
                      )
                      :intboz_type :Decimal
                    )
                    :length (IntegerConstant
                      :n 10
                      :type (Integer
                        :kind 4
                      )
                      :intboz_type :Decimal
                    )
                  )
                ]
                :codims []
                :len_expr nil
                :sym_subclass nil
                :type nil
              )
            ]
            :stat (Var
              :v (SymbolRef 1 "stat")
            )
            :errmsg nil
            :source nil
          )
          (ReAlloc
            :args [
              (alloc_arg
                :a (Var
                  :v (SymbolRef 1 "a")
                )
                :dims [
                  (dimension
                    :start (IntegerConstant
                      :n 1
                      :type (Integer
                        :kind 4
                      )
                      :intboz_type :Decimal
                    )
                    :length (IntegerConstant
                      :n 20
                      :type (Integer
                        :kind 4
                      )
                      :intboz_type :Decimal
                    )
                  )
                ]
                :codims []
                :len_expr nil
                :sym_subclass nil
                :type nil
              )
            ]
            :shape_differs (IntegerCompare
              :left (ArraySize
                :v (Var
                  :v (SymbolRef 1 "a")
                )
                :dim (IntegerConstant
                  :n 1
                  :type (Integer
                    :kind 4
                  )
                  :intboz_type :Decimal
                )
                :type (Integer
                  :kind 4
                )
                :value nil
              )
              :op :NotEq
              :right (IntegerConstant
                :n 20
                :type (Integer
                  :kind 4
                )
                :intboz_type :Decimal
              )
              :type (Logical
                :kind 4
              )
              :value nil
            )
          )
          (ExplicitDeallocate
            :vars [
              (Var
                :v (SymbolRef 1 "a")
              )
            ]
          )
          (Nullify
            :vars [
              (Var
                :v (SymbolRef 1 "p")
              )
            ]
          )
          (ImplicitDeallocate
            :vars [
              (Var
                :v (SymbolRef 1 "a")
              )
            ]
          )
        ]
        :global_init nil
      )
    }
  )
  :items []
  :global_init nil
)

See Also

Allocate, Assignment, ExplicitDeallocate, ArraySize