Errors in the Intent of Arguments
| SimCon Home | Ref Manual Home |
What Are Intent Errors?
Fortran allows the arguments to sub-programs to be declared:
The intent is declared in INTENT statements or on an INTENT clause within a type declaration statement. The intent is not required to be declared, but declaration of intent improves the checking by compilers. Note that at least three other intents are possible and are recognised internally by fpt:
No provision is made to declare these intents explicitly.
The Fortran standard explicitly states that a declared intent may be used to guide code generation. Therefore, an INTENT(IN) object need not be exported on exit from a sub-program and an INTENT(OUT) object need not be imported when the sub-program is called. Therefore at least the following classes of intent error are possible:
Do Compilers Trap These Errors?
These issues were tested on gfortran, ifort, Compaq Visual Fortran (CVF) and FTN95)
INTENT(IN): All compilers which we have tested trap INTENT(IN) errors when the argument is assigned across an equals sign in the code of the routine itself. Compilers do not detect this class of error when the argument is passed down into a secondary routine where it is assigned, unless the interface to the secondary routine is visible in the primary routine and the intent is declared in that interface. No error occurs at run-time. Therefore a large number of INTENT(IN) errors are found in code.
INTENT(OUT): None of the compilers we have tested detect INTENT(OUT) errors. An error may occur at run-time if the argument has never been initialised.
Access Violation: These errors are always trapped when the intent of the argument is explicitly declared and the interface is visble to the caller. The compilers tested do not detect this error if the intent is not declared. Run-time errors always occur.
Write to Expression: Again, these errors are always trapped when the intent of the argument is declared and the interface is visible. They are not detected when the intent is not declared. No run-time errors occur. This is a dangerous situation. Compilers generate a temporary variable to hold the value of the expression. This temporary is modified in the sub-program call. Optimising compilers may re-use it elsewhere.
Sub-program and Label: These errors were trapped by all compilers tested.
Detecting Intent Errors
fpt always reports errors in Access Violation and Write to Expression. No command is required to make these checks. Occurrences can be corrected automatically by the command:
CORRECT INCONSISTENT ARGUMENTS
The command to check for INTENT(IN) and INTENT(OUT) violations is
The beginning of the report for WRFV3.6.1 is shown below:
Check of INTENT Declarations ============================ Arguments declared INTENT(IN) which are assigned ------------------------------------------------ Name Scope Use/COMMON Address Type Size Value/Bounds ---- ----- ---------- ------- ---- ---- ------------ comm wrf_ext_write_field Formal Input-Output Argument INTEGER *4 df comm wrf_ext_write_field_arr Formal Input-Output Argument INTEGER *4 df comm wrf_ext_read_field_arr Formal Input-Output Argument INTEGER *4 df config_flags med_initialdata_input Formal Input-Output Argument grid_config_rec_type *35164 df
The report ends with a summary:
Total number of arguments 60752 Declared INTENT(IN) 33126 Declared INTENT(OUT) 5309 Declared INTENT(INOUT) 7177 No INTENT declaration 15115 Sub-program formal arguments 25 INTENT(IN) Violations 138 0.4% INTENT(OUT) Violations 0 0.0% Additional possible INTENT(OUT) Violations 2044 38.5%
Note that there are no certain INTENT(OUT) violations, but that read accesses to a number of INTENT(OUT) arguments may be reachable before the argument is assigned.
The large number of intent violations could cause problems if the declarations were used to guide code generation. Two additional fpt commands were developed to assess the risk:
REMOVE INTENT SPECIFICATIONS and ENFORCE INTENT IN AS DECLARED
The command REMOVE INTENT SPECIFICATIONS strips every non-mandatory INTENT specification from the code. The only INTENT specifications which remain are those for the arguments of pure and elemental sub-programs. In WRFV3.6.1 over 45,000 specifications are removed. Test runs of WRF showed no changes, the results were consistent to a single bit. We conclude that the compilers used, gfortran and ifort, do not use the INTENT specifications in code generation.
The command ENFORCE INTENT IN AS DECLARED modifies the code to prevent any possible violations. INTENT(IN) arguments are copied to temporaries if there is any possibility that they could be written to. Again, test runs of WRF showed no changes. The WRF code does not depend on the side effects of intent violations.
Copyright ©1995 to 2018 Software Validation Ltd. All rights reserved.