What do allocations (triggering GC) depend on?

I want to compile code with help of StaticCompiler. So I need to avoid GC allocations.
I want to understand when GC allocations occur. In the following code 3 GC allocations happen:

using StaticTools

mutable struct D

  t::MallocArray{Int64}

  function D()
    t = MallocArray{Int64}(undef,1)
    new(t)
  end

end

function str2num(str::MallocString)::Int64
  len = length(str)
  zahl = 0
  for i in 1:len
    zahl += (Int(str[i])-64) * 26 ^ (len-i)
  end
  zahl 
end

function g(d::D,r::Int64,str::MallocString)
  idx = r * 1 + 0
  d.t[idx] = str2num(str)
end

function f()
  d = D()  
  g(d,1,m"A")
  0
end

@time f()

Under some conditions no GC allocations occur:

If there is only a + or a * in g(), then no GC allocation occur:
idx = r * 1 or
idx = r + 0

If there is no struct, then no GC allocations occur: Use the code above, omit the struct D and modify g() and f() to:

function g(t::MallocArray,r::Int64,str::MallocString)
  idx = r * 1 + 0
  t[idx] = str2num(str)
  t
end

function f()
  t = MallocArray{Int64}(undef,1)
  t = g(t,1,m"A")
  0
end

Considerung function str2num(), when there is no Int(), then no GC allocations happen:

zahl += (Int(65)-64) * 26 ^ (len-i)

Similarly, when in str2num() there is no for-loop, or at least there is no variable in the number of iterations, then there are no GC
alocations:

  zahl = 0
  i = 1
  zahl += (Int(str[i])-64) * 26 ^ (len-i)

or

  for i in 1:1
    ...
  end

When do GC allocations occur?

It typically allocates when using mutable structs. Under 1.10.3 allocations go away if the D struct is immutable. Under 1.12-DEV it does not allocate with a mutable struct either.