https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123106
--- Comment #4 from David Malcolm <dmalcolm at gcc dot gnu.org> --- (In reply to Andrew Pinski from comment #0) Sorry, my Fortran knowledge is practically non-existent. Here's your example on Compiler Explorer: https://godbolt.org/z/86hrKedfe > Take: > ``` > print *, foo_io() > > contains > > function foo_io() > integer :: foo_io(2) > > print * , "foo" > foo_io = [42, 42] > end function > > end > ``` > > This currently hangs at runtime because it is violating the Fortran > restriction on output statements. It would be interesting to have analyzer > support to detect this case. > > The IR: > ``` > MAIN() { > ... > dt_parm.6.common.unit = 6; > _gfortran_st_write (&dt_parm.6); > ... > foo_io (&atmp.7); [static-chain: &FRAME.13]; > ... > _gfortran_st_write_done (&dt_parm.6); > } > > foo_io () { > ... > dt_parm.0.common.unit = 6; > _gfortran_st_write (&dt_parm.0); > } > > ``` Am I correct in thinking that: _gfortran_st_write (&dt_parm.6); blocks and acquires a lock on dt_parm.6.common.unit, that: _gfortran_st_write_done (&dt_parm.6); releases the lock on dt_parm.6.common.unit, and thus we'd have something like: MAIN() { ... _gfortran_st_write (&dt_parm.6); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | (1) lock acquired here ... foo_io (&atmp.7); [static-chain: &FRAME.13]; within foo_io (): ... dt_parm.0.common.unit = 6; _gfortran_st_write (&dt_parm.0); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | (2) deadlock; lock on unit 6 already acquired at (1) If so, this could potentially implemented via a new state machine in -fanalyzer, mapping "unit" values to a bool "locked" state, where a call to _gfortran_st_write transitions the unit to "locked" and _gfortran_st_write_done transitions it to "unlocked", and the default state is "unlocked". Are there other states or transitions that would be needed? What would a warning ideally look like at the source level?
