gfc_trans_create_temp_arrays has been using loop bounds to set array temporary bounds; this is a sensible thing to do as gfc_conv_loop_setup tries to set loop bounds according to the most information (especially w.r.t. constantness) it can find. For plain arrays like `a(:,:)' or `b(:,1,:)', it's quite simple, as there is a direct maping between loop bounds and temporary bounds. Now, if we are creating a temporary for the argument of `transpose(a(:,1,1,:))' we have to be careful as the loop has a direct mapping to `transpose(a(:,1,1:))', while the temporary has a direct mapping to `a(:,1,1,:)'. It is currently done (in get_array_ref_dim) by looking at the dim array which is in the case above: {3,0}. If we want to know the bounds of the first dimension (or zero'th as it is zero-based) of the temporary, we see that dim[0] == 3, and that there is one element in dim that is below 3. Thus bounds are to be taken from dimension number one (the second as it is zero-based) of the loop. The same function is used to retrieve the shape dimension from the loop dimension in gfc_conv_loop_setup. Now, let's throw sum in the mix. Now we have to generate bounds properly when generating a temporary either for the inner or outer arrays in the following cases: sum(a(:,1,1,:), dim=1) transpose(sum(a(:,1,:,:), dim=1)) sum(transpose(a(:,1,1,:)), dim=1) For the outer array, in all cases, the current implementation can be kept as is, as the inner loop can be completely ignored. For the inner array, however, we have to take care of the current loop, and all the parents ones it is in, so this patch adds a walk towards the outer array. With this change, the function can't be used as is anymore in gfc_conv_loop_setup, as it is ignoring nested loops: we have to start from the most nested array slice before calling the function. This patch also does that. OK?