This is g77.info, produced by makeinfo version 4.0 from g77.texi.

INFO-DIR-SECTION Programming
START-INFO-DIR-ENTRY
* g77: (g77).                  The GNU Fortran compiler.
END-INFO-DIR-ENTRY
   This file documents the use and the internals of the GNU Fortran
(`g77') compiler.  It corresponds to the GCC-3.0 version of `g77'.

   Published by the Free Software Foundation 59 Temple Place - Suite 330
Boston, MA 02111-1307 USA

   Copyright (C) 1995,1996,1997,1998,1999,2000,2001 Free Software
Foundation, Inc.

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with the
Invariant Sections being "GNU General Public License" and "Funding Free
Software", the Front-Cover texts being (a) (see below), and with the
Back-Cover Texts being (b) (see below).  A copy of the license is
included in the section entitled "GNU Free Documentation License".

   (a) The FSF's Front-Cover Text is:

   A GNU Manual

   (b) The FSF's Back-Cover Text is:

   You have freedom to copy and modify this GNU Manual, like GNU
software.  Copies published by the Free Software Foundation raise
funds for GNU development.

   Contributed by James Craig Burley (<craig@jcb-sc.com>).  Inspired by
a first pass at translating `g77-0.5.16/f/DOC' that was contributed to
Craig by David Ronis (<ronis@onsager.chem.mcgill.ca>).


File: g77.info,  Node: Two-pass Code,  Next: Why Two Passes,  Up: Two-pass Design

Two-pass Code
-------------

   Most of the code that turns the first pass (parsing) into a second
pass for code generation is in `gcc/gcc/f/std.c'.

   It has external functions, called mainly by siblings in
`gcc/gcc/f/stc.c', that record the information on statements and
expressions in the order they are seen in the source code.  These
functions save that information.

   It also has an external function that revisits that information,
calling the siblings in `gcc/gcc/f/ste.c', which handles the actual
code generation (by generating GBEL code, that is, by calling GBE
routines to represent and specify expressions, statements, and so on).


File: g77.info,  Node: Why Two Passes,  Prev: Two-pass Code,  Up: Two-pass Design

Why Two Passes
--------------

   The need for two passes was not immediately evident during the
design and implementation of the code in the FFE that was to produce
GBEL.  Only after a few kludges, to handle things like
incorrectly-guessed `ASSIGN' label nature, had been implemented, did
enough evidence pile up to make it clear that `std.c' had to be
introduced to intercept, save, then revisit as part of a second pass,
the digested contents of a program unit.

   Other such missteps have occurred during the evolution of the FFE,
because of the different goals of the FFE and the GBE.

   Because the GBE's original, and still primary, goal was to directly
support the GNU C language, the GBEL, and the GBE itself, requires more
complexity on the part of most front ends than it requires of `gcc''s.

   For example, the GBEL offers an interface that permits the `gcc'
front end to implement most, or all, of the language features it
supports, without the front end having to make use of non-user-defined
variables.  (It's almost certainly the case that all of K&R C, and
probably ANSI C as well, is handled by the `gcc' front end without
declaring such variables.)

   The FFE, on the other hand, must resort to a variety of "tricks" to
achieve its goals.

   Consider the following C code:

     int
     foo (int a, int b)
     {
       int c = 0;
     
       if ((c = bar (c)) == 0)
         goto done;
     
       quux (c << 1);
     
     done:
       return c;
     }

   Note what kinds of objects are declared, or defined, before their
use, and before any actual code generation involving them would
normally take place:

   * Return type of function

   * Entry point(s) of function

   * Dummy arguments

   * Variables

   * Initial values for variables

   Whereas, the following items can, and do, suddenly appear "out of
the blue" in C:

   * Label references

   * Function references

   Not surprisingly, the GBE faithfully permits the latter set of items
to be "discovered" partway through GBEL "programs", just as they are
permitted to in C.

   Yet, the GBE has tended, at least in the past, to be reticent to
fully support similar "late" discovery of items in the former set.

   This makes Fortran a poor fit for the "safe" subset of GBEL.
Consider:

           FUNCTION X (A, ARRAY, ID1)
           CHARACTER*(*) A
           DOUBLE PRECISION X, Y, Z, TMP, EE, PI
           REAL ARRAY(ID1*ID2)
           COMMON ID2
           EXTERNAL FRED
     
           ASSIGN 100 TO J
           CALL FOO (I)
           IF (I .EQ. 0) PRINT *, A(0)
           GOTO 200
     
           ENTRY Y (Z)
           ASSIGN 101 TO J
     200   PRINT *, A(1)
           READ *, TMP
           GOTO J
     100   X = TMP * EE
           RETURN
     101   Y = TMP * PI
           CALL FRED
           DATA EE, PI /2.71D0, 3.14D0/
           END

   Here are some observations about the above code, which, while
somewhat contrived, conforms to the FORTRAN 77 and Fortran 90 standards:

   * The return type of function `X' is not known until the `DOUBLE
     PRECISION' line has been parsed.

   * Whether `A' is a function or a variable is not known until the
     `PRINT *, A(0)' statement has been parsed.

   * The bounds of the array of argument `ARRAY' depend on a
     computation involving the subsequent argument `ID1' and the
     blank-common member `ID2'.

   * Whether `Y' and `Z' are local variables, additional function entry
     points, or dummy arguments to additional entry points is not known
     until the `ENTRY' statement is parsed.

   * Similarly, whether `TMP' is a local variable is not known until
     the `READ *, TMP' statement is parsed.

   * The initial values for `EE' and `PI' are not known until after the
     `DATA' statement is parsed.

   * Whether `FRED' is a function returning type `REAL' or a subroutine
     (which can be thought of as returning type `void' _or_, to support
     alternate returns in a simple way, type `int') is not known until
     the `CALL FRED' statement is parsed.

   * Whether `100' is a `FORMAT' label or the label of an executable
     statement is not known until the `X =' statement is parsed.
     (These two types of labels get _very_ different treatment,
     especially when `ASSIGN''ed.)

   * That `J' is a local variable is not known until the first `ASSIGN'
     statement is parsed.  (This happens _after_ executable code has
     been seen.)

   Very few of these "discoveries" can be accommodated by the GBE as it
has evolved over the years.  The GBEL doesn't support several of them,
and those it might appear to support don't always work properly,
especially in combination with other GBEL and GBE features, as
implemented in the GBE.

   (Had the GBE and its GBEL originally evolved to support `g77', the
shoe would be on the other foot, so to speak--most, if not all, of the
above would be directly supported by the GBEL, and a few C constructs
would probably not, as they are in reality, be supported.  Both this
mythical, and today's real, GBE caters to its GBEL by, sometimes,
scrambling around, cleaning up after itself--after discovering that
assumptions it made earlier during code generation are incorrect.
That's not a great design, since it indicates significant code paths
that might be rarely tested but used in some key production
environments.)

   So, the FFE handles these discrepancies--between the order in which
it discovers facts about the code it is compiling, and the order in
which the GBEL and GBE support such discoveries--by performing what
amounts to two passes over each program unit.

   (A few ambiguities can remain at that point, such as whether, given
`EXTERNAL BAZ' and no other reference to `BAZ' in the program unit, it
is a subroutine, a function, or a block-data--which, in C-speak,
governs its declared return type.  Fortunately, these distinctions are
easily finessed for the procedure, library, and object-file interfaces
supported by `g77'.)


File: g77.info,  Node: Challenges Posed,  Next: Transforming Statements,  Prev: Two-pass Design,  Up: Front End

Challenges Posed
================

   Consider the following Fortran code, which uses various extensions
(including some to Fortran 90):

     SUBROUTINE X(A)
     CHARACTER*(*) A
     COMPLEX CFUNC
     INTEGER*2 CLOCKS(200)
     INTEGER IFUNC
     
     CALL SYSTEM_CLOCK (CLOCKS (IFUNC (CFUNC ('('//A//')'))))

   The above poses the following challenges to any Fortran compiler
that uses run-time interfaces, and a run-time library, roughly similar
to those used by `g77':

   * Assuming the library routine that supports `SYSTEM_CLOCK' expects
     to set an `INTEGER*4' variable via its `COUNT' argument, the
     compiler must make available to it a temporary variable of that
     type.

   * Further, after the `SYSTEM_CLOCK' library routine returns, the
     compiler must ensure that the temporary variable it wrote is
     copied into the appropriate element of the `CLOCKS' array.  (This
     assumes the compiler doesn't just reject the code, which it should
     if it is compiling under some kind of a "strict" option.)

   * To determine the correct index into the `CLOCKS' array, (putting
     aside the fact that the index, in this particular case, need not
     be computed until after the `SYSTEM_CLOCK' library routine
     returns), the compiler must ensure that the `IFUNC' function is
     called.

     That requires evaluating its argument, which requires, for `g77'
     (assuming `-ff2c' is in force), reserving a temporary variable of
     type `COMPLEX' for use as a repository for the return value being
     computed by `CFUNC'.

   * Before invoking `CFUNC', is argument must be evaluated, which
     requires allocating, at run time, a temporary large enough to hold
     the result of the concatenation, as well as actually performing
     the concatenation.

   * The large temporary needed during invocation of `CFUNC' should,
     ideally, be deallocated (or, at least, left to the GBE to dispose
     of, as it sees fit) as soon as `CFUNC' returns, which means before
     `IFUNC' is called (as it might need a lot of dynamically allocated
     memory).

   `g77' currently doesn't support all of the above, but, so that it
might someday, it has evolved to handle at least some of the above
requirements.

   Meeting the above requirements is made more challenging by
conforming to the requirements of the GBEL/GBE combination.


File: g77.info,  Node: Transforming Statements,  Next: Transforming Expressions,  Prev: Challenges Posed,  Up: Front End

Transforming Statements
=======================

   Most Fortran statements are given their own block, and, for
temporary variables they might need, their own scope.  (A block is what
distinguishes `{ foo (); }' from just `foo ();' in C.  A scope is
included with every such block, providing a distinct name space for
local variables.)

   Label definitions for the statement precede this block, so `10 PRINT
*, I' is handled more like `fl10: { ... }' than `{ fl10: ... }' (where
`fl10' is just a notation meaning "Fortran Label 10" for the purposes
of this document).

* Menu:

* Statements Needing Temporaries::
* Transforming DO WHILE::
* Transforming Iterative DO::
* Transforming Block IF::
* Transforming SELECT CASE::


File: g77.info,  Node: Statements Needing Temporaries,  Next: Transforming DO WHILE,  Up: Transforming Statements

Statements Needing Temporaries
------------------------------

   Any temporaries needed during, but not beyond, execution of a
Fortran statement, are made local to the scope of that statement's
block.

   This allows the GBE to share storage for these temporaries among the
various statements without the FFE having to manage that itself.

   (The GBE could, of course, decide to optimize management of these
temporaries.  For example, it could, theoretically, schedule some of
the computations involving these temporaries to occur in parallel.
More practically, it might leave the storage for some temporaries
"live" beyond their scopes, to reduce the number of manipulations of
the stack pointer at run time.)

   Temporaries needed across distinct statement boundaries usually are
associated with Fortran blocks (such as `DO'/`END DO').  (Also, there
might be temporaries not associated with blocks at all--these would be
in the scope of the entire program unit.)

   Each Fortran block _should_ get its own block/scope in the GBE.
This is best, because it allows temporaries to be more naturally
handled.  However, it might pose problems when handling labels (in
particular, when they're the targets of `GOTO's outside the Fortran
block), and generally just hassling with replicating parts of the `gcc'
front end (because the FFE needs to support an arbitrary number of
nested back-end blocks if each Fortran block gets one).

   So, there might still be a need for top-level temporaries, whose
"owning" scope is that of the containing procedure.

   Also, there seems to be problems declaring new variables after
generating code (within a block) in the back end, leading to, e.g.,
`label not defined before binding contour' or similar messages, when
compiling with `-fstack-check' or when compiling for certain targets.

   Because of that, and because sometimes these temporaries are not
discovered until in the middle of of generating code for an expression
statement (as in the case of the optimization for `X**I'), it seems
best to always pre-scan all the expressions that'll be expanded for a
block before generating any of the code for that block.

   This pre-scan then handles discovering and declaring, to the back
end, the temporaries needed for that block.

   It's also important to treat distinct items in an I/O list as
distinct statements deserving their own blocks.  That's because there's
a requirement that each I/O item be fully processed before the next one,
which matters in cases like `READ (*,*), I, A(I)'--the element of `A'
read in the second item _must_ be determined from the value of `I' read
in the first item.


File: g77.info,  Node: Transforming DO WHILE,  Next: Transforming Iterative DO,  Prev: Statements Needing Temporaries,  Up: Transforming Statements

Transforming DO WHILE
---------------------

   `DO WHILE(expr)' _must_ be implemented so that temporaries needed to
evaluate `expr' are generated just for the test, each time.

   Consider how `DO WHILE (A//B .NE. 'END'); ...; END DO' is
transformed:

     for (;;)
       {
         int temp0;
     
         {
           char temp1[large];
     
           libg77_catenate (temp1, a, b);
           temp0 = libg77_ne (temp1, 'END');
         }
     
         if (! temp0)
           break;
     
         ...
       }

   In this case, it seems like a time/space tradeoff between allocating
and deallocating `temp1' for each iteration and allocating it just once
for the entire loop.

   However, if `temp1' is allocated just once for the entire loop, it
could be the wrong size for subsequent iterations of that loop in cases
like `DO WHILE (A(I:J)//B .NE. 'END')', because the body of the loop
might modify `I' or `J'.

   So, the above implementation is used, though a more optimal one can
be used in specific circumstances.


File: g77.info,  Node: Transforming Iterative DO,  Next: Transforming Block IF,  Prev: Transforming DO WHILE,  Up: Transforming Statements

Transforming Iterative DO
-------------------------

   An iterative `DO' loop (one that specifies an iteration variable) is
required by the Fortran standards to be implemented as though an
iteration count is computed before entering the loop body, and that
iteration count used to determine the number of times the loop body is
to be performed (assuming the loop isn't cut short via `GOTO' or
`EXIT').

   The FFE handles this by allocating a temporary variable to contain
the computed number of iterations.  Since this variable must be in a
scope that includes the entire loop, a GBEL block is created for that
loop, and the variable declared as belonging to the scope of that block.


File: g77.info,  Node: Transforming Block IF,  Next: Transforming SELECT CASE,  Prev: Transforming Iterative DO,  Up: Transforming Statements

Transforming Block IF
---------------------

   Consider:

     SUBROUTINE X(A,B,C)
     CHARACTER*(*) A, B, C
     LOGICAL LFUNC
     
     IF (LFUNC (A//B)) THEN
       CALL SUBR1
     ELSE IF (LFUNC (A//C)) THEN
       CALL SUBR2
     ELSE
       CALL SUBR3
     END

   The arguments to the two calls to `LFUNC' require dynamic allocation
(at run time), but are not required during execution of the `CALL'
statements.

   So, the scopes of those temporaries must be within blocks inside the
block corresponding to the Fortran `IF' block.

   This cannot be represented "naturally" in vanilla C, nor in GBEL.
The `if', `elseif', `else', and `endif' constructs provided by both
languages must, for a given `if' block, share the same C/GBE block.

   Therefore, any temporaries needed during evaluation of `expr' while
executing `ELSE IF(expr)' must either have been predeclared at the top
of the corresponding `IF' block, or declared within a new block for
that `ELSE IF'--a block that, since it cannot contain the `else' or
`else if' itself (due to the above requirement), actually implements
the rest of the `IF' block's `ELSE IF' and `ELSE' statements within an
inner block.

   The FFE takes the latter approach.


File: g77.info,  Node: Transforming SELECT CASE,  Prev: Transforming Block IF,  Up: Transforming Statements

Transforming SELECT CASE
------------------------

   `SELECT CASE' poses a few interesting problems for code generation,
if efficiency and frugal stack management are important.

   Consider `SELECT CASE (I('PREFIX'//A))', where `A' is
`CHARACTER*(*)'.  In a case like this--basically, in any case where
largish temporaries are needed to evaluate the expression--those
temporaries should not be "live" during execution of any of the `CASE'
blocks.

   So, evaluation of the expression is best done within its own block,
which in turn is within the `SELECT CASE' block itself (which contains
the code for the CASE blocks as well, though each within their own
block).

   Otherwise, we'd have the rough equivalent of this pseudo-code:

     {
       char temp[large];
     
       libg77_catenate (temp, 'prefix', a);
     
       switch (i (temp))
         {
         case 0:
           ...
         }
     }

   And that would leave temp[large] in scope during the CASE blocks
(although a clever back end *could* see that it isn't referenced in
them, and thus free that temp before executing the blocks).

   So this approach is used instead:

     {
       int temp0;
     
       {
         char temp1[large];
     
         libg77_catenate (temp1, 'prefix', a);
         temp0 = i (temp1);
       }
     
       switch (temp0)
         {
         case 0:
           ...
         }
     }

   Note how `temp1' goes out of scope before starting the switch, thus
making it easy for a back end to free it.

   The problem _that_ solution has, however, is with `SELECT
CASE('prefix'//A)' (which is currently not supported).

   Unless the GBEL is extended to support arbitrarily long character
strings in its `case' facility, the FFE has to implement `SELECT CASE'
on `CHARACTER' (probably excepting `CHARACTER*1') using a cascade of
`if', `elseif', `else', and `endif' constructs in GBEL.

   To prevent the (potentially large) temporary, needed to hold the
selected expression itself (`'prefix'//A'), from being in scope during
execution of the `CASE' blocks, two approaches are available:

   * Pre-evaluate all the `CASE' tests, producing an integer ordinal
     that is used, a la `temp0' in the earlier example, as if `SELECT
     CASE(temp0)' had been written.

     Each corresponding `CASE' is replaced with `CASE(I)', where I is
     the ordinal for that case, determined while, or before, generating
     the cascade of `if'-related constructs to cope with `CHARACTER'
     selection.

   * Make `temp0' above just large enough to hold the longest `CASE'
     string that'll actually be compared against the expression (in
     this case, `'prefix'//A').

     Since that length must be constant (because `CASE' expressions are
     all constant), it won't be so large, and, further, `temp1' need
     not be dynamically allocated, since normal `CHARACTER' assignment
     can be used into the fixed-length `temp0'.

   Both of these solutions require `SELECT CASE' implementation to be
changed so all the corresponding `CASE' statements are seen during the
actual code generation for `SELECT CASE'.


File: g77.info,  Node: Transforming Expressions,  Next: Internal Naming Conventions,  Prev: Transforming Statements,  Up: Front End

Transforming Expressions
========================

   The interactions between statements, expressions, and subexpressions
at program run time can be viewed as:

     ACTION(EXPR)

   Here, ACTION is the series of steps performed to effect the
statement, and EXPR is the expression whose value is used by ACTION.

   Expanding the above shows a typical order of events at run time:

     Evaluate EXPR
     Perform ACTION, using result of evaluation of EXPR
     Clean up after evaluating EXPR

   So, if evaluating EXPR requires allocating memory, that memory can
be freed before performing ACTION only if it is not needed to hold the
result of evaluating EXPR.  Otherwise, it must be freed no sooner than
after ACTION has been performed.

   The above are recursive definitions, in the sense that they apply to
subexpressions of EXPR.

   That is, evaluating EXPR involves evaluating all of its
subexpressions, performing the ACTION that computes the result value of
EXPR, then cleaning up after evaluating those subexpressions.

   The recursive nature of this evaluation is implemented via
recursive-descent transformation of the top-level statements, their
expressions, _their_ subexpressions, and so on.

   However, that recursive-descent transformation is, due to the nature
of the GBEL, focused primarily on generating a _single_ stream of code
to be executed at run time.

   Yet, from the above, it's clear that multiple streams of code must
effectively be simultaneously generated during the recursive-descent
analysis of statements.

   The primary stream implements the primary ACTION items, while at
least two other streams implement the evaluation and clean-up items.

   Requirements imposed by expressions include:

   * Whether the caller needs to have a temporary ready to hold the
     value of the expression.

   * Other stuff???


File: g77.info,  Node: Internal Naming Conventions,  Prev: Transforming Expressions,  Up: Front End

Internal Naming Conventions
===========================

   Names exported by FFE modules have the following
(regular-expression) forms.  Note that all names beginning `ffeMOD' or
`FFEMOD', where MOD is lowercase or uppercase alphanumerics,
respectively, are exported by the module `ffeMOD', with the source code
doing the exporting in `MOD.h'.  (Usually, the source code for the
implementation is in `MOD.c'.)

   Identifiers that don't fit the following forms are not considered
exported, even if they are according to the C language.  (For example,
they might be made available to other modules solely for use within
expansions of exported macros, not for use within any source code in
those other modules.)

`ffeMOD'
     The single typedef exported by the module.

`FFEUMOD_[A-Z][A-Z0-9_]*'
     (Where UMOD is the uppercase for of MOD.)

     A `#define' or `enum' constant of the type `ffeMOD'.

`ffeMOD[A-Z][A-Z][a-z0-9]*'
     A typedef exported by the module.

     The portion of the identifier after `ffeMOD' is referred to as
     `ctype', a capitalized (mixed-case) form of `type'.

`FFEUMOD_TYPE[A-Z][A-Z0-9_]*[A-Z0-9]?'
     (Where UMOD is the uppercase for of MOD.)

     A `#define' or `enum' constant of the type `ffeMODTYPE', where
     TYPE is the lowercase form of CTYPE in an exported typedef.

`ffeMOD_VALUE'
     A function that does or returns something, as described by VALUE
     (see below).

`ffeMOD_VALUE_INPUT'
     A function that does or returns something based primarily on the
     thing described by INPUT (see below).

   Below are names used for VALUE and INPUT, along with their
definitions.

`col'
     A column number within a line (first column is number 1).

`file'
     An encapsulation of a file's name.

`find'
     Looks up an instance of some type that matches specified criteria,
     and returns that, even if it has to create a new instance or crash
     trying to find it (as appropriate).

`initialize'
     Initializes, usually a module.  No type.

`int'
     A generic integer of type `int'.

`is'
     A generic integer that contains a true (non-zero) or false (zero)
     value.

`len'
     A generic integer that contains the length of something.

`line'
     A line number within a source file, or a global line number.

`lookup'
     Looks up an instance of some type that matches specified criteria,
     and returns that, or returns nil.

`name'
     A `text' that points to a name of something.

`new'
     Makes a new instance of the indicated type.  Might return an
     existing one if appropriate--if so, similar to `find' without
     crashing.

`pt'
     Pointer to a particular character (line, column pairs) in the
     input file (source code being compiled).

`run'
     Performs some herculean task.  No type.

`terminate'
     Terminates, usually a module.  No type.

`text'
     A `char *' that points to generic text.


File: g77.info,  Node: Diagnostics,  Next: Index,  Prev: Front End,  Up: Top

Diagnostics
***********

   Some diagnostics produced by `g77' require sufficient explanation
that the explanations are given below, and the diagnostics themselves
identify the appropriate explanation.

   Identification uses the GNU Info format--specifically, the `info'
command that displays the explanation is given within square brackets
in the diagnostic.  For example:

     foo.f:5: Invalid statement [info -f g77 M FOOEY]

   More details about the above diagnostic is found in the `g77' Info
documentation, menu item `M', submenu item `FOOEY', which is displayed
by typing the UNIX command `info -f g77 M FOOEY'.

   Other Info readers, such as EMACS, may be just as easily used to
display the pertinent node.  In the above example, `g77' is the Info
document name, `M' is the top-level menu item to select, and, in that
node (named `Diagnostics', the name of this chapter, which is the very
text you're reading now), `FOOEY' is the menu item to select.

* Menu:

* CMPAMBIG::    Ambiguous use of intrinsic.
* EXPIMP::      Intrinsic used explicitly and implicitly.
* INTGLOB::     Intrinsic also used as name of global.
* LEX::         Various lexer messages
* GLOBALS::     Disagreements about globals.
* LINKFAIL::    When linking `f771' fails.
* Y2KBAD::      Use of non-Y2K-compliant intrinsic.


File: g77.info,  Node: CMPAMBIG,  Next: EXPIMP,  Up: Diagnostics

`CMPAMBIG'
==========

     Ambiguous use of intrinsic INTRINSIC ...

   The type of the argument to the invocation of the INTRINSIC
intrinsic is a `COMPLEX' type other than `COMPLEX(KIND=1)'.  Typically,
it is `COMPLEX(KIND=2)', also known as `DOUBLE COMPLEX'.

   The interpretation of this invocation depends on the particular
dialect of Fortran for which the code was written.  Some dialects
convert the real part of the argument to `REAL(KIND=1)', thus losing
precision; other dialects, and Fortran 90, do no such conversion.

   So, GNU Fortran rejects such invocations except under certain
circumstances, to avoid making an incorrect assumption that results in
generating the wrong code.

   To determine the dialect of the program unit, perhaps even whether
that particular invocation is properly coded, determine how the result
of the intrinsic is used.

   The result of INTRINSIC is expected (by the original programmer) to
be `REAL(KIND=1)' (the non-Fortran-90 interpretation) if:

   * It is passed as an argument to a procedure that explicitly or
     implicitly declares that argument `REAL(KIND=1)'.

     For example, a procedure with no `DOUBLE PRECISION' or `IMPLICIT
     DOUBLE PRECISION' statement specifying the dummy argument
     corresponding to an actual argument of `REAL(Z)', where `Z' is
     declared `DOUBLE COMPLEX', strongly suggests that the programmer
     expected `REAL(Z)' to return `REAL(KIND=1)' instead of
     `REAL(KIND=2)'.

   * It is used in a context that would otherwise not include any
     `REAL(KIND=2)' but where treating the INTRINSIC invocation as
     `REAL(KIND=2)' would result in unnecessary promotions and
     (typically) more expensive operations on the wider type.

     For example:

          DOUBLE COMPLEX Z
          ...
          R(1) = T * REAL(Z)

     The above example suggests the programmer expected the real part
     of `Z' to be converted to `REAL(KIND=1)' before being multiplied
     by `T' (presumed, along with `R' above, to be type `REAL(KIND=1)').

     Otherwise, the conversion would have to be delayed until after the
     multiplication, requiring not only an extra conversion (of `T' to
     `REAL(KIND=2)'), but a (typically) more expensive multiplication
     (a double-precision multiplication instead of a single-precision
     one).

   The result of INTRINSIC is expected (by the original programmer) to
be `REAL(KIND=2)' (the Fortran 90 interpretation) if:

   * It is passed as an argument to a procedure that explicitly or
     implicitly declares that argument `REAL(KIND=2)'.

     For example, a procedure specifying a `DOUBLE PRECISION' dummy
     argument corresponding to an actual argument of `REAL(Z)', where
     `Z' is declared `DOUBLE COMPLEX', strongly suggests that the
     programmer expected `REAL(Z)' to return `REAL(KIND=2)' instead of
     `REAL(KIND=1)'.

   * It is used in an expression context that includes other
     `REAL(KIND=2)' operands, or is assigned to a `REAL(KIND=2)'
     variable or array element.

     For example:

          DOUBLE COMPLEX Z
          DOUBLE PRECISION R, T
          ...
          R(1) = T * REAL(Z)

     The above example suggests the programmer expected the real part
     of `Z' to _not_ be converted to `REAL(KIND=1)' by the `REAL()'
     intrinsic.

     Otherwise, the conversion would have to be immediately followed by
     a conversion back to `REAL(KIND=2)', losing the original, full
     precision of the real part of `Z', before being multiplied by `T'.

   Once you have determined whether a particular invocation of INTRINSIC
expects the Fortran 90 interpretation, you can:

   * Change it to `DBLE(EXPR)' (if INTRINSIC is `REAL') or
     `DIMAG(EXPR)' (if INTRINSIC is `AIMAG') if it expected the Fortran
     90 interpretation.

     This assumes EXPR is `COMPLEX(KIND=2)'--if it is some other type,
     such as `COMPLEX*32', you should use the appropriate intrinsic,
     such as the one to convert to `REAL*16' (perhaps `DBLEQ()' in
     place of `DBLE()', and `QIMAG()' in place of `DIMAG()').

   * Change it to `REAL(INTRINSIC(EXPR))', otherwise.  This converts to
     `REAL(KIND=1)' in all working Fortran compilers.

   If you don't want to change the code, and you are certain that all
ambiguous invocations of INTRINSIC in the source file have the same
expectation regarding interpretation, you can:

   * Compile with the `g77' option `-ff90', to enable the Fortran 90
     interpretation.

   * Compile with the `g77' options `-fno-f90 -fugly-complex', to
     enable the non-Fortran-90 interpretations.

   *Note REAL() and AIMAG() of Complex::, for more information on this
issue.

   Note: If the above suggestions don't produce enough evidence as to
whether a particular program expects the Fortran 90 interpretation of
this ambiguous invocation of INTRINSIC, there is one more thing you can
try.

   If you have access to most or all the compilers used on the program
to create successfully tested and deployed executables, read the
documentation for, and _also_ test out, each compiler to determine how
it treats the INTRINSIC intrinsic in this case.  (If all the compilers
don't agree on an interpretation, there might be lurking bugs in the
deployed versions of the program.)

   The following sample program might help:

           PROGRAM JCB003
     C
     C Written by James Craig Burley 1997-02-23.
     C
     C Determine how compilers handle non-standard REAL
     C and AIMAG on DOUBLE COMPLEX operands.
     C
           DOUBLE COMPLEX Z
           REAL R
           Z = (3.3D0, 4.4D0)
           R = Z
           CALL DUMDUM(Z, R)
           R = REAL(Z) - R
           IF (R .NE. 0.) PRINT *, 'REAL() is Fortran 90'
           IF (R .EQ. 0.) PRINT *, 'REAL() is not Fortran 90'
           R = 4.4D0
           CALL DUMDUM(Z, R)
           R = AIMAG(Z) - R
           IF (R .NE. 0.) PRINT *, 'AIMAG() is Fortran 90'
           IF (R .EQ. 0.) PRINT *, 'AIMAG() is not Fortran 90'
           END
     C
     C Just to make sure compiler doesn't use naive flow
     C analysis to optimize away careful work above,
     C which might invalidate results....
     C
           SUBROUTINE DUMDUM(Z, R)
           DOUBLE COMPLEX Z
           REAL R
           END

   If the above program prints contradictory results on a particular
compiler, run away!


File: g77.info,  Node: EXPIMP,  Next: INTGLOB,  Prev: CMPAMBIG,  Up: Diagnostics

`EXPIMP'
========

     Intrinsic INTRINSIC referenced ...

   The INTRINSIC is explicitly declared in one program unit in the
source file and implicitly used as an intrinsic in another program unit
in the same source file.

   This diagnostic is designed to catch cases where a program might
depend on using the name INTRINSIC as an intrinsic in one program unit
and as a global name (such as the name of a subroutine or function) in
another, but `g77' recognizes the name as an intrinsic in both cases.

   After verifying that the program unit making implicit use of the
intrinsic is indeed written expecting the intrinsic, add an `INTRINSIC
INTRINSIC' statement to that program unit to prevent this warning.

   This and related warnings are disabled by using the `-Wno-globals'
option when compiling.

   Note that this warning is not issued for standard intrinsics.
Standard intrinsics include those described in the FORTRAN 77 standard
and, if `-ff90' is specified, those described in the Fortran 90
standard.  Such intrinsics are not as likely to be confused with user
procedures as intrinsics provided as extensions to the standard by
`g77'.


File: g77.info,  Node: INTGLOB,  Next: LEX,  Prev: EXPIMP,  Up: Diagnostics

`INTGLOB'
=========

     Same name `INTRINSIC' given ...

   The name INTRINSIC is used for a global entity (a common block or a
program unit) in one program unit and implicitly used as an intrinsic
in another program unit.

   This diagnostic is designed to catch cases where a program intends
to use a name entirely as a global name, but `g77' recognizes the name
as an intrinsic in the program unit that references the name, a
situation that would likely produce incorrect code.

   For example:

     INTEGER FUNCTION TIME()
     ...
     END
     ...
     PROGRAM SAMP
     INTEGER TIME
     PRINT *, 'Time is ', TIME()
     END

   The above example defines a program unit named `TIME', but the
reference to `TIME' in the main program unit `SAMP' is normally treated
by `g77' as a reference to the intrinsic `TIME()' (unless a
command-line option that prevents such treatment has been specified).

   As a result, the program `SAMP' will _not_ invoke the `TIME'
function in the same source file.

   Since `g77' recognizes `libU77' procedures as intrinsics, and since
some existing code uses the same names for its own procedures as used
by some `libU77' procedures, this situation is expected to arise often
enough to make this sort of warning worth issuing.

   After verifying that the program unit making implicit use of the
intrinsic is indeed written expecting the intrinsic, add an `INTRINSIC
INTRINSIC' statement to that program unit to prevent this warning.

   Or, if you believe the program unit is designed to invoke the
program-defined procedure instead of the intrinsic (as recognized by
`g77'), add an `EXTERNAL INTRINSIC' statement to the program unit that
references the name to prevent this warning.

   This and related warnings are disabled by using the `-Wno-globals'
option when compiling.

   Note that this warning is not issued for standard intrinsics.
Standard intrinsics include those described in the FORTRAN 77 standard
and, if `-ff90' is specified, those described in the Fortran 90
standard.  Such intrinsics are not as likely to be confused with user
procedures as intrinsics provided as extensions to the standard by
`g77'.


File: g77.info,  Node: LEX,  Next: GLOBALS,  Prev: INTGLOB,  Up: Diagnostics

`LEX'
=====

     Unrecognized character ...
     Invalid first character ...
     Line too long ...
     Non-numeric character ...
     Continuation indicator ...
     Label at ... invalid with continuation line indicator ...
     Character constant ...
     Continuation line ...
     Statement at ... begins with invalid token

   Although the diagnostics identify specific problems, they can be
produced when general problems such as the following occur:

   * The source file contains something other than Fortran code.

     If the code in the file does not look like many of the examples
     elsewhere in this document, it might not be Fortran code.  (Note
     that Fortran code often is written in lower case letters, while
     the examples in this document use upper case letters, for
     stylistic reasons.)

     For example, if the file contains lots of strange-looking
     characters, it might be APL source code; if it contains lots of
     parentheses, it might be Lisp source code; if it contains lots of
     bugs, it might be C++ source code.

   * The source file contains free-form Fortran code, but `-ffree-form'
     was not specified on the command line to compile it.

     Free form is a newer form for Fortran code.  The older, classic
     form is called fixed form.

     Fixed-form code is visually fairly distinctive, because numerical
     labels and comments are all that appear in the first five columns
     of a line, the sixth column is reserved to denote continuation
     lines, and actual statements start at or beyond column 7.  Spaces
     generally are not significant, so if you see statements such as
     `REALX,Y' and `DO10I=1,100', you are looking at fixed-form code.
     Comment lines are indicated by the letter `C' or the symbol `*' in
     column 1.  (Some code uses `!' or `/*' to begin in-line comments,
     which many compilers support.)

     Free-form code is distinguished from fixed-form source primarily
     by the fact that statements may start anywhere.  (If lots of
     statements start in columns 1 through 6, that's a strong indicator
     of free-form source.)  Consecutive keywords must be separated by
     spaces, so `REALX,Y' is not valid, while `REAL X,Y' is.  There are
     no comment lines per se, but `!' starts a comment anywhere in a
     line (other than within a character or Hollerith constant).

     *Note Source Form::, for more information.

   * The source file is in fixed form and has been edited without
     sensitivity to the column requirements.

     Statements in fixed-form code must be entirely contained within
     columns 7 through 72 on a given line.  Starting them "early" is
     more likely to result in diagnostics than finishing them "late",
     though both kinds of errors are often caught at compile time.

     For example, if the following code fragment is edited by following
     the commented instructions literally, the result, shown afterward,
     would produce a diagnostic when compiled:

          C On XYZZY systems, remove "C" on next line:
          C     CALL XYZZY_RESET

     The result of editing the above line might be:

          C On XYZZY systems, remove "C" on next line:
               CALL XYZZY_RESET

     However, that leaves the first `C' in the `CALL' statement in
     column 6, making it a comment line, which is not really what the
     author intended, and which is likely to result in one of the
     above-listed diagnostics.

     _Replacing_ the `C' in column 1 with a space is the proper change
     to make, to ensure the `CALL' keyword starts in or after column 7.

     Another common mistake like this is to forget that fixed-form
     source lines are significant through only column 72, and that,
     normally, any text beyond column 72 is ignored or is diagnosed at
     compile time.

     *Note Source Form::, for more information.

   * The source file requires preprocessing, and the preprocessing is
     not being specified at compile time.

     A source file containing lines beginning with `#define',
     `#include', `#if', and so on is likely one that requires
     preprocessing.

     If the file's suffix is `.f', `.for', or `.FOR', the file normally
     will be compiled _without_ preprocessing by `g77'.

     Change the file's suffix from `.f' to `.F' (or, on systems with
     case-insensitive file names, to `.fpp' or `.FPP'), from `.for' to
     `.fpp', or from `.FOR' to `.FPP'.  `g77' compiles files with such
     names _with_ preprocessing.

     Or, learn how to use `gcc''s `-x' option to specify the language
     `f77-cpp-input' for Fortran files that require preprocessing.
     *Note gcc: (Using and Porting GNU CC)Overall Options.

   * The source file is preprocessed, and the results of preprocessing
     result in syntactic errors that are not necessarily obvious to
     someone examining the source file itself.

     Examples of errors resulting from preprocessor macro expansion
     include exceeding the line-length limit, improperly starting,
     terminating, or incorporating the apostrophe or double-quote in a
     character constant, improperly forming a Hollerith constant, and
     so on.

     *Note Options Controlling the Kind of Output: Overall Options, for
     suggestions about how to use, and not use, preprocessing for
     Fortran code.


File: g77.info,  Node: GLOBALS,  Next: LINKFAIL,  Prev: LEX,  Up: Diagnostics

`GLOBALS'
=========

     Global name NAME defined at ... already defined...
     Global name NAME at ... has different type...
     Too many arguments passed to NAME at ...
     Too few arguments passed to NAME at ...
     Argument #N of NAME is ...

   These messages all identify disagreements about the global procedure
named NAME among different program units (usually including NAME
itself).

   Whether a particular disagreement is reported as a warning or an
error can depend on the relative order of the disagreeing portions of
the source file.

   Disagreements between a procedure invocation and the _subsequent_
procedure itself are, usually, diagnosed as errors when the procedure
itself _precedes_ the invocation.  Other disagreements are diagnosed
via warnings.

   This distinction, between warnings and errors, is due primarily to
the present tendency of the `gcc' back end to inline only those
procedure invocations that are _preceded_ by the corresponding
procedure definitions.  If the `gcc' back end is changed to inline
"forward references", in which invocations precede definitions, the
`g77' front end will be changed to treat both orderings as errors,
accordingly.

   The sorts of disagreements that are diagnosed by `g77' include
whether a procedure is a subroutine or function; if it is a function,
the type of the return value of the procedure; the number of arguments
the procedure accepts; and the type of each argument.

   Disagreements regarding global names among program units in a
Fortran program _should_ be fixed in the code itself.  However, if that
is not immediately practical, and the code has been working for some
time, it is possible it will work when compiled with the `-fno-globals'
option.

   The `-fno-globals' option causes these diagnostics to all be warnings
and disables all inlining of references to global procedures (to avoid
subsequent compiler crashes and bad-code generation).  Use of the
`-Wno-globals' option as well as `-fno-globals' suppresses all of these
diagnostics.  (`-Wno-globals' by itself disables only the warnings, not
the errors.)

   After using `-fno-globals' to work around these problems, it is wise
to stop using that option and address them by fixing the Fortran code,
because such problems, while they might not actually result in bugs on
some systems, indicate that the code is not as portable as it could be.
In particular, the code might appear to work on a particular system,
but have bugs that affect the reliability of the data without
exhibiting any other outward manifestations of the bugs.


File: g77.info,  Node: LINKFAIL,  Next: Y2KBAD,  Prev: GLOBALS,  Up: Diagnostics

`LINKFAIL'
==========

On AIX 4.1, `g77' might not build with the native (non-GNU) tools due
to a linker bug in coping with the `-bbigtoc' option which leads to a
`Relocation overflow' error.  The GNU linker is not recommended on
current AIX versions, though; it was developed under a now-unsupported
version.  This bug is said to be fixed by `update PTF U455193 for APAR
IX75823'.

   Compiling with `-mminimal-toc' might solve this problem, e.g. by
adding
     BOOT_CFLAGS='-mminimal-toc -O2 -g'
   to the `make bootstrap' command line.


File: g77.info,  Node: Y2KBAD,  Prev: LINKFAIL,  Up: Diagnostics

`Y2KBAD'
========

     Intrinsic `NAME', invoked at (^), known to be non-Y2K-compliant...

   This diagnostic indicates that the specific intrinsic invoked by the
name NAME is known to have an interface that is not Year-2000 (Y2K)
compliant.

   *Note Year 2000 (Y2K) Problems::.

