To: J3 J3/07-257r1 Subject: Draft Annex for OWG-V From: Dan Nagle Date: 2008 August 12 Draft of the Fortran Annex of the OWG-V TR This Annex provides Fortran-specific advice for the items in clause 6, specifically the 6.x.5 Avoiding the vulnerability or mitigating its effects subclause. This annex does not repeat the other sections of each vulnerability. Therefore, readers will find OWG-V n0134 helpful when reading this document. A copy of n0134.pdf is in the Tutorials subdirectory of the members area on the J3 server. DRAFT %%% 6.1 BRS Leveraging Experience Avoid the use of decremental features. %%% 6.2 BQF Unspecified Behavior The Fortran term is processor-dependent behavior (see also 6.2). Use only forms and relationships where the result of the program execution does not depend upon the processor choice from among the possibilities defined by the processor dependency. %%% 6.3 EWF Undefined Behavior Use only those forms and relationships where the Fortran standard provides an interpretation. %%% 6.4 FAB Implementation-defined Behavior The Fortran term is processor-dependent behavior (see also 6.2). See Annex A of f08. %%% 6.5 MEM Deprecated Language Features See Annex B of f08. Avoid the use deleted or obsolescent features. %%% 6.6 BVQ Unspecified Functionality No specific Fortran recommendation. %%% 6.7 NMP Pre-processor Directives No Fortran preprocessor. %%% 6.8 NAI Choice of Clear Names Avoid names differing only in case. %%% 6.9 AJN Choice of Filenames and other External Identifiers Take care with external identifiers as they are all processor-dependent. %%% 6.10 XYR Unused Variable Use IMPLICIT NONE to require explicit declaration of all variable names. Use translator options to generate warning when unused variables are encountered. Use a compiler option to warn of undeclared variables if use of IMPLICIT NONE is impractical. %%% 6.11 YOW Identifier Name Reuse Do not use BLOCKs to override names from the outer scope. Note that Fortran doesn't have a scope resolution operator. When using a BLOCK to declare a new name, ensure that the name is unique across all enclosing scopes and enclosed scopes. Use consistent names within groups of related entities. Ensure that all names are 63 characters or fewer. %%% 6.12 IHN Type System Always use IMPLICIT NONE. Avoid implicit type conversions and mixed-mode arithmetic. Use compiler options to enable warnings where appropriate. %%% 6.13 STR Bit Representations Always use the Fortran bit model ordering. Do not manipulate bits of negative numbers without documenting the treatment of negative numbers on the target platform. %%% 6.14 PLF Floating-point Arithmetic Do not test for real equality. Compare real quantities with a tolerance rather than for strict equality. Do not use real loop counters. Use the inquiry intrinsics to determine the characteristics of the real model rather than computing them. Use the intrinsics to get or set the fields of real data. Avoid the use of bit constants as floating point constants. Do not assume knowledge of the rounding mode of the translator. Explicitly control the rounding mode of input/output transfers. %%% 6.15 CCB Enumerator Issues Use enumerators only when interfacing to C programs. %%% 6.16 FLC Numeric Conversion Errors Check the value of input data. Check values before critical operations. Set an error to occur when appropriate. Use explicit conversion intrinsics to indicate intention. Always use an explicit kind as part of a real constant. Be aware of the unexpected properties when using list directed input. %%% 6.17 CJM String Termination Use character operations rather than explicit loops. When explicit loops are necessary, use inquiry intrinsics to determine the loop count. %%% 6.18 XYX Boundary Beginning Violation Check values used as array indices. Use whole array operations when possible to avoid array index calculations. Use bounds checking to find out-of-bounds conditions. %%% 6.19 XYZ Unchecked Array Indexing Check values used as array indices. Use whole-array operations when possible to avoid array index calculations. Use inquiry intrinsics to determine array bounds. %%% 6.20 XYW Buffer Overflow in Stack Check values used as array indices. Use whole-array operations when possible to avoid array index calculations. Use inquiry intrinsics to determine array bounds. Use explicit ALLOCATE statements to place large object on the heap. Indicate in code where implicit allocate/deallocate is expected. Do not use superfluous "(:)" to indicate whole array operations. %%% 6.21 XZB Buffer Overflow in Heap Indicate in code where implicit allocate or deallocate is expected. Check values used as array indices. Use whole-array operations when possible to avoid array index calculations. Use inquiry intrinsics to determine array bounds. %%% 6.22 HFC Pointer Casting and Pointer Type Changes Does not happen in Fortran. %%% 6.23 RVG Pointer Arithmetic Does not happen in Fortran. %%% 6.24 XYH Null Pointer Dereference Verify that pointers and allocatables are defined and are not null. %%% 6.25 XYK Dangling Reference to Heap Use finalizers to clear pointers and allocatables in derived types. Use automatic allocation/deallocation. Allocate and deallocate in the same module to ease checking. %%% 6.26 SYM Templates and Generics Not applicable to Fortran. %%% 6.27 LAV Initialization of Variables Ensure all variables are initialized before use. Provide a default initialization for derived type variables. Keep variable usage confined to one module to make analysis tractable. Ensure that defined assignment assigns to all components. Use constructors rather than component-wise assignments. Avoid use of COMMON. Do not rely upon variables being initialized to zero. %%% 6.28 XYY Wrap-around Error Check values for proper range between bit operations and arithmetic operations. Never use bit operations where an intrinsic procedure performs the intended calculation (for example, using and-with-sign-bit in place of SIGN()). %%% 6.29 XZI Sign Extension Error Use explicit conversion between differently sized integers. Do not use TRANSFER(). Do not use EQUIVALENCE. %%% 6.30 JCW Operator Precedence/Order of Evaluation Use parenthesis where order of evaluation is critical. Use auxiliary variables to order operations. %%% 6.31 SAM Side-effects and Order of Evaluation Use pure functions whenever possible. Use subroutines when side effects are needed. %%% 6.32 KOA Likely Incorrect Expression Simplify expressions. Use variables to hold partial results of long expressions. Vertically align similar terms in long expressions to ease visual checking. %%% 6.33 XYQ Dead and Deactivated Code Dead code or unreachable code should be removed. If available, use compiler options to warn of unreachable code. %%% 6.34 CLL Switch Statement and Static Analysis Ensure that SELECT CASE constructs cover all cases. Use a CASE DEFAULT clause as needed. %%% 6.35 EOJ Demarcation of Flow Control Always use block forms of DO-loops. Always use END- statements. Use named constructs for all but possibly the smallest constructs. Indent code. Use a syntax-highlighting editor. %%% 6.36 TEX Loop Control Variables Use the loop induction variable inside a loop (as opposed to an auxiliary variable), especially as an array index. Check that procedure references within a loop do not modify the loop variable. %%% 6.37 XZH Off-by-one Error Use inquiry intrinsics to set loop limits. Use counted DO-loops, DO CONCURRENT or FORALL for array computations. Use whole array operations if possible. Never use sentinel values for loop control. %%% 6.38 EWD Structured Programming Use block structures in preference to GO TO statements. Name the target structure of CYCLE and EXIT statements. Do not use alternate returns. Do not use branch specifiers for input/output statements; use the status variable and test its value instead. %%% 6.39 CSJ Passing Parameters and Return Values Use argument intents. Minimize side effects. %%% 6.40 DCM Dangling References to Stack Frames Never associate a pointer having a greater longevity with a target having a shorter longevity. Use compiler options where available to warn of possible situations where the the pointer outlives the target. %%% 6.41 OTR Subprogram Signature Mismatch Always use explicit interfaces. Use optional arguments when needed. Use argument intents. %%% 6.42 GDL Recursion Minimize the use of recursion. Convert recursive calculations to iterative calculations. Guarantee a recursive calculation has a maximum depth. %%% 6.43 NZN Returning Error Status Treat errors locally if possible. Return a status variable. %%% 6.44 RUE Termination Strategy Each application should have an error handling strategy. When an application is parallel, whether to kill the task, or halt the task but preserve its resources, or kill the application, must be decided. %%% 6.45 AMV Type-breaking Reinterpretation of Data Do not use EQUIVALENCE to change type. Do not use TRANSFER. Ensure consistent definition of COMMON blocks. %%% 6.46 XYL Memory Leak Ensure ALLOCATE statements match DEALLOCATE statements. Ensure that each DEALLOCATE statement is reached via all possible paths from the corresponding ALLOCATE statements. Use automatic deallocation where possible. Use allocatable variables rather than pointers. %%% 6.47 TRJ Use of Libraries Use libraries with explicit interfaces (modules). %%% 6.48 NYY Dynamically-linked Code and Self-modifying Code Consider the use of static linking when useful.