[patch, Fortran] PR61933 Inquire on Internal Units

Jerry DeLisle jvdelisle@charter.net
Tue Jan 20 03:34:00 GMT 2015


ping

This PR has been marked as a regression, so I suppose we ought to get it fixed.

On 01/18/2015 09:10 PM, Jerry DeLisle wrote:
> I reopened this PR to do some cleanup and to address a use case presented by
> Joost in comment #7 of the subject PR.
>
> The fundamental problem: if the variable containing the unit number in an
> INQUIRE statement is of type KIND greater than 4 and the value is outside the
> range of a KIND=4 we cannot test for it within the run-time library.  Unit
> numbers are passed to the run-time in the IOPARM structures as a KIND=4. KIND=8
> are cast into the KIND=4.  The test case gfortran.dg/negative_unit_int8.f
> illustrates a case where a bogus unit number can get passed to the library.
>
> To resolve this previously we built range checks in trans_io.c
> (set_parameter_value) that tests the unit numbers and issues an error call to
> the run-time library.  This is fine for all statements except INQUIRE which
> should not give an error. However, we do want to identify such an out-of-range
> unit number as not existing.
>
> This patch changes this by renaming the previous set_parameter_value to
> set_parameter_value_chk.  I then created a new version of set_parameter_value
> that does no checking so that it can be used where generating errors is not
> needed.  I have created two new functions which build code that tests for the
> out of range cases specific to INQUIRE.  If a bad unit number is found, the UNIT
> value in the IOPARM structure is set to -2, a new reserved value. (after this
> patch we will have reserved values -3 thru -9 still available for future uses)
>
> The definition of unit existence is adjusted to be any negative unit currently
> connected having been created with NEWUNIT and all KIND=4 positive values.  A -2
> indicating an invalid unit will, by default, return EXISTS=false.
>
> The behind the scenes testing is never seen in user space as shown here with an
> -fdump-tree-original example from the negative_unit_int8.f .
>
> For non-INQUIRE cases:
>
>      D.3384 = i;
>      if (D.3384 < -2147483647)
>        {
>          _gfortran_generate_error (&dt_parm.0, 5005, &"Unit number in I/O
> statement too small"
>      [1]{lb: 1 sz: 1});
>        }
>      if (D.3384 > 2147483647)
>        {
>          _gfortran_generate_error (&dt_parm.0, 5005, &"Unit number in I/O
> statement too large"
>      [1]{lb: 1 sz: 1});
>        }
>      dt_parm.0.common.unit = (integer(kind=4)) D.3384;
>
> For the new INQUIRE case:
>
>      integer(kind=8) i;
>
> --- snip ---
>
>      inquire_parm.4.common.unit = (integer(kind=4)) i;<---notice the conversion
> to kind=4 here
>      D.3393 = i;
>      if (D.3393 < 0)
>        {
>          inquire_parm.4.common.unit = -2;
>        }
>      if (D.3393 > 2147483647)
>        {
>          inquire_parm.4.common.unit = -2;
>        }
>
> When all is acceptable, common.unit is untouched and the normal assignment has
> happened.  The users variable, in this case i, is untouched as well because of
> the temporary D.3393.  The IOPARM stucture is also temporary and not used again.
>
> The patch updates the test case mentioned above.
>
> Regression tested on x86-64 and Joost's case in the PR now works as expected.
>
> OK for trunk?
>
> Regards,
>
> Jerry
>
>
> 2015-01-18  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
>
>      PR fortran/61933
>      * trans-io.c (set_parameter_value): Delete use of has_iostat.
>      Redefine to not generate any runtime error check calls.
>      (set_parameter_value_chk): Rename of the former
>      set_parameter_value with the runtimr error checks and fix
>      whitespace. (gfc_trans_io_inquire_check): New function that
>      builds a runtime conditional block to set the INQUIRE
>      common parameter block unit number to -2 when unit numbers
>      exceed positive KIND=4 limits. (set_parameter_value_inquire):
>      New function that builds the conditional expressions and calls
>      gfc_trans_io_inquire_check. (gfc_trans_open): Whitespace.  For
>      unit, use the renamed set_parameter_value_chk.
>      (gfc_trans_close): Likewise use renamed function.
>      (build_filepos): Whitespace and use renamed function.
>      (gfc_trans_inquire): Whitespace and for unit use
>      set_parameter_value and set_parameter_value_inquire.
>      (gfc_trans_wait): Remove p->iostat from call to
>      set_parameter_value. Use new set_parameter_value_chk for unit.
>      (build_dt): Use the new set_parameter_value without p->iostat
>      and fix whitespace. Use set_parameter_value_chk for unit.
>
> 2015-01-18  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
>
>      PR libgfortran/61933
>      * io/inquire.c (inquire_via_unit): Set existing to true for
>      any negative unit that is currently connected and any positive
>      units within range of KIND=4 value.  The unit value for any out
>      of range case that may occur if the user is using a KIND=8 will
>      have been set to -2 which is reserved and can never be opened,
>      and therefore the unit does not exist.



More information about the Gcc-patches mailing list