[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