<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/56921>56921</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [FLANG] Use after free in "mask" when using WHERE construct.
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            flang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          Leporacanthicus
      </td>
    </tr>
</table>

<pre>
    The following program fails on valgrind with use after free, and as it stands (on Linux at least) fails with a segfault. Changing the size to a smaller one, and the segfault goes away [1].

This code is derived from a mms_verify_1 in the file mms.f90 in [SNAP](|https://github.com/lanl/SNAP).

```
program w
  implicit none

  integer(4), parameter :: nx = 64000
  REAL(8), parameter :: zero = 0.0
  REAL(8), parameter :: one = 1.0
  REAL(8), parameter :: tolr = 1e-12

  REAL(8), ALLOCATABLE, DIMENSION(:) :: ref_flux
  REAL(8), DIMENSION(nx) :: df

  ALLOCATE( ref_flux(nx) )

  ref_flux = zero
  
  WHERE( ABS( ref_flux ) < tolr )
     ref_flux = one
     df = zero
  END WHERE

  IF ( ALLOCATED( ref_flux ) ) DEALLOCATE( ref_flux )

end program w
```

Swap the line df = zero with ref_flux = one and it works just fine for some reason!

I believe the problem lies in the mask generation and usage, and in particular how the cleanup for the mask is done.

I edited the generated mlir to move the fir,freemem a few lines down (after its second use), and then it works.

[This ticket is raised as a copy of https://github.com/flang-compiler/f18-llvm-project/issues/1511 which I Iwill now close, as that repo is locked]

[1] This has to do with how malloc works - for "large" allocations, it uses mmap, and callsmunmap directly when it frees. For small allocations, it has a large chunk of heap memory, and when free is called, the memory remains present, it is just added to a list of freed memory, available for future allocations - so there is no segfault for smaller allocations.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyNVU1z4jgQ_TXm0hXKNp8-cCBAdqliM1uTTO0xJey2rYksUZIMYX79dgtDIJOZmhTB2FL3e_269bw1xXH2XCOURilzkLqCnTWVFQ2UQioHRsNeqMpKXcBB-hpahyBKjxZKixilCxC0JBxID87TbwdROqWwjdTtGwgPCoXzUZp1GUMWAQ6rUrTK92FRC10xsiceTv5A8IY3NEIpgjH6ghI2dHFQGXQgDuII0eg-iUbLfhQvo3h--n6upYPcFAh0LdDKPRbE2DSUuWncy54elceXBKQOaUupkBf6ZRbzM8r59Dj_l9JSNdFkUXu_c9FgHqUP9Kmohnbbz01DN0poRZewPc1uWETjuPuE27O0h9MtgGx2SuaknOYqrwJpSXus0BL6kLKyAjtBscjKM4_BHPQb_VrCeBjH8Tns62q-oZjpr2J-oDUhKu7_cQxxCyHJn4d4o-wpBu-S9LayD7HzzebLYv48v9-s-Ha5_mf1-LT-8si6s97ZOafF8qVU7dsv8lwH6reruKK8xe8ACW36nvMSQ8ludp93hGpYvfPC-frf36uvIdf8_uk6JZwoLDotznmB_26SXlofloryJ6TV47JDuWG2foAA25Wz_Bmc_perz8r9WCbS4fownB9G9_T9dBC7cFyUpJm4ono61R_LCoeWpvtg7KuD763zdM40m40FZxqkAOGMjtLkGmQNW1QS9xiQiNZWYUOIdNy7w9oI9woVarTCS7IahmmdqC5GQftoJL3MWyUs1OYQwnJyIt3uAvwlDdsDUe3fMsBCejwZTodDd42Slr2pMR23UtL5XLAPNsjGUuIhKMMpD5q7c3JK6R35Vm4CTezmtTM0fRHo1jlG98HCqIZX9MzSCukwOK0gY9sdwZTwG1cqyZaqO_q9I2ez_CCZ3im1b-5I0e-YkyM_SOdadPQjGSUJHGqZ17CG9UEqRY50IMGMO2lKRGqycos7w1yUIVYFm-MtZbZhCLxrDjGkw2kyuAXs5ybvhuEudCFKU2oQ9y2FsBr66RiSVCGtHHmy2J3lymmPa1pNj6CQlopQR6J90pDb4PrwwLPFUJ8krIN4ARHyutWvQUOkbNQ_Y49nnJCS83GtDEq10lKYmbCRhGiE1I6mEx1q3-WX3ZCLouDh4beYknRPKJytuIbZ08tQ0GQHHcrWtxavGZNAzjCiDSS0eX_xlecKabKuIvo9nCXjUTaOszSb9IrZoMgGmeh56RXOqDkPm_njX9ygbzev8PC2S1M-DNyGUHvr-H0cPIdmTTtv29z3e61Vs9-9CGm6ustnQzYaZ2nSq2fT8TSf5MNtlqTbNJtO8kFZDEU6TCYD3A7FqEe6oHJMmQiFOaYrEe_JWRqnaTyNh0k8GI7G_aQcZsVWDCbjIpuIbR4NY26M6jOHvrFVz84CnW1bOVrkbrj3ReGcrDQGdTi_aH1t7GxDU25FLrSnE9G6XqhgFuj_D2rz2jM">