From abe330b83f6e1650d705bfc1b2fbe8d648934bbe Mon Sep 17 00:00:00 2001 From: Alasdair Gray Date: Sun, 21 Jun 2026 17:42:39 -0400 Subject: [PATCH] Fix potential stack overflow in overset initialisation --- src/overset/oversetUtilities.F90 | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/overset/oversetUtilities.F90 b/src/overset/oversetUtilities.F90 index 36f7ad86c..32afb3a35 100644 --- a/src/overset/oversetUtilities.F90 +++ b/src/overset/oversetUtilities.F90 @@ -1240,7 +1240,7 @@ subroutine addToFringeList(fringeList, n, fringe) integer(kind=intType), intent(inout) :: n ! Working Paramters - integer(kind=intType) :: fSize + integer(kind=intType) :: fSize, i type(fringeType), dimension(:), pointer :: tmpFringePtr fSize = size(fringeList) @@ -1255,8 +1255,14 @@ subroutine addToFringeList(fringeList, n, fringe) ! Allocate new space allocate (fringeList(int(1.5 * fSize))) - ! Copy exsitng values - fringeList(1:fSize) = tmpFringePtr(1:fSize) + ! Copy values to new array. Note: we deliberately use an explicit loop here rather than whole-array + ! assignment (`fringeList(1:fSize) = tmpFringePtr(1:fSize)`). Because fringeList and tmpFringePtr are both + ! pointers, a whole-array copy forces the compiler to materialise a temporary array. Under -Ofast, ` + ! -fstack-arrays` is enabled which means this temporary array will be stack allocated. Depending on the size + ! of the mesh, the fringe list can exceed the default stack size, leading to a stack overflow. + do i = 1, fSize + fringeList(i) = tmpFringePtr(i) + end do ! Free original memory deallocate (tmpFringePtr) @@ -1274,6 +1280,7 @@ subroutine addToFringeBuffer(intBuffer, realBuffer, n, fringe) use constants use block, only: fringeType + use utils, only: reallocateInteger2, reallocateReal2 implicit none @@ -1285,8 +1292,6 @@ subroutine addToFringeBuffer(intBuffer, realBuffer, n, fringe) ! Working Paramters integer(kind=intType) :: fSize - integer(kind=intType), dimension(:, :), pointer :: tmpInt - real(kind=realType), dimension(:, :), pointer :: tmpReal fSize = size(intBuffer, 2) ! Increment n for next item @@ -1294,20 +1299,9 @@ subroutine addToFringeBuffer(intBuffer, realBuffer, n, fringe) if (n > fSize) then - ! Pointers to existing data: - tmpInt => intBuffer - tmpReal => realBuffer - - ! Allocate new space - allocate (intBuffer(5, int(1.5 * fSize))) - allocate (realBuffer(4, int(1.5 * fSize))) - - ! Copy exsitng values - intBuffer(:, 1:fSize) = tmpInt(:, 1:fSize) - realBuffer(:, 1:fSize) = tmpReal(:, 1:fSize) - - ! Free original memory - deallocate (tmpInt, tmpReal) + ! Increase the buffer sizes by 50%. + call reallocateInteger2(intBuffer, 5, int(1.5 * fSize), 5, fSize, .true.) + call reallocateReal2(realBuffer, 4, int(1.5 * fSize), 4, fSize, .true.) end if