https://gcc.gnu.org/g:dff66a690f6d47963e5cb96677d0e194b85948fa
commit r16-1696-gdff66a690f6d47963e5cb96677d0e194b85948fa Author: Andre Vehreschild <ve...@gcc.gnu.org> Date: Wed Jun 25 09:12:35 2025 +0200 Fortran: Fix out of bounds access in structure constructor's clean up [PR120711] A structure constructor's generated clean up code was using an offset variable, which was manipulated before the clean up was run leading to an out of bounds access. PR fortran/120711 gcc/fortran/ChangeLog: * trans-array.cc (gfc_trans_array_ctor_element): Store the value of the offset for reuse. gcc/testsuite/ChangeLog: * gfortran.dg/asan/array_constructor_1.f90: New test. Diff: --- gcc/fortran/trans-array.cc | 10 ++++++---- .../gfortran.dg/asan/array_constructor_1.f90 | 23 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 3d274439895d..7be2d7b11a62 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -1991,14 +1991,17 @@ static void gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc, tree offset, gfc_se * se, gfc_expr * expr) { - tree tmp; + tree tmp, offset_eval; gfc_conv_expr (se, expr); /* Store the value. */ tmp = build_fold_indirect_ref_loc (input_location, gfc_conv_descriptor_data_get (desc)); - tmp = gfc_build_array_ref (tmp, offset, NULL); + /* The offset may change, so get its value now and use that to free memory. + */ + offset_eval = gfc_evaluate_now (offset, &se->pre); + tmp = gfc_build_array_ref (tmp, offset_eval, NULL); if (expr->expr_type == EXPR_FUNCTION && expr->ts.type == BT_DERIVED && expr->ts.u.derived->attr.alloc_comp) @@ -3150,8 +3153,7 @@ finish: the reference. */ if ((expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS) && finalblock.head != NULL_TREE) - gfc_add_block_to_block (&loop->post, &finalblock); - + gfc_prepend_expr_to_block (&loop->post, finalblock.head); } diff --git a/gcc/testsuite/gfortran.dg/asan/array_constructor_1.f90 b/gcc/testsuite/gfortran.dg/asan/array_constructor_1.f90 new file mode 100644 index 000000000000..45eafacd5a67 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/asan/array_constructor_1.f90 @@ -0,0 +1,23 @@ +!{ dg-do run } + +! Contributed by Christopher Albert <alb...@tugraz.at> + +program grow_type_array + type :: container + integer, allocatable :: arr(:) + end type container + + type(container), allocatable :: list(:) + + list = [list, new_elem(5)] + + deallocate(list) + +contains + + type(container) function new_elem(s) result(out) + integer :: s + allocate(out%arr(s)) + end function new_elem + +end program grow_type_array