[gcc r16-1696] Fortran: Fix out of bounds access in structure constructor's clean up [PR120711]
Andre Vehreschild
vehre@gcc.gnu.org
Thu Jun 26 08:44:53 GMT 2025
https://gcc.gnu.org/g:dff66a690f6d47963e5cb96677d0e194b85948fa
commit r16-1696-gdff66a690f6d47963e5cb96677d0e194b85948fa
Author: Andre Vehreschild <vehre@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 <albert@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
More information about the Gcc-cvs
mailing list