diff options
Diffstat (limited to 'gcc/fortran')
| -rw-r--r-- | gcc/fortran/ChangeLog | 24 | ||||
| -rw-r--r-- | gcc/fortran/gfc-internals.texi | 101 | ||||
| -rw-r--r-- | gcc/fortran/invoke.texi | 15 | ||||
| -rw-r--r-- | gcc/fortran/iresolve.c | 28 |
4 files changed, 158 insertions, 10 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 420218fa57c..a54a0b14909 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,27 @@ +2008-06-29 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/36341 + * iresolve.c (gfc_resolve_matmul): Copy shapes + from arguments. + +2008-06-29 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + * invoke.texi: Add documentation for runtime behavior of + -fno-range-check. + +2008-06-28 Daniel Kraft <d@domob.eu> + + * gfc-internals.texi (section gfc_code): Extended documentation about + gfc_code in the internal datastructures chapter including details about + how IF, DO and SELECT blocks look like and an example for how the + block-chaining works. + +2008-06-25 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/36526 + * interface.c (check_intents): Correct error where the actual + arg was checked for a pointer argument, rather than the formal. + 2008-06-24 Paul Thomas <pault@gcc.gnu.org> PR fortran/34371 diff --git a/gcc/fortran/gfc-internals.texi b/gcc/fortran/gfc-internals.texi index 0a91310fe7d..dfe5d161842 100644 --- a/gcc/fortran/gfc-internals.texi +++ b/gcc/fortran/gfc-internals.texi @@ -284,9 +284,12 @@ should exhaust all possible valid combinations of content for these structures. @menu -* gfc_code:: Representation of Executable Statements +* gfc_code:: Representation of Executable Statements. @end menu +@c gfc_code +@c -------- + @node gfc_code @section @code{gfc_code} @cindex statement chaining @@ -309,13 +312,95 @@ current statement. If the current statement is one of @code{IF}, @code{DO}, @code{SELECT} it starts a block, i.e.@: a nested level in the program. In order to represent this, the @code{block} member is set to point to a -@code{gfc_code} structure whose @code{block} member points to the -block in question. The @code{SELECT} and @code{IF} statements may -contain various blocks (the chain of @code{ELSE IF} and @code{ELSE} -blocks or the various @code{CASE}s, respectively). - -@c What would be nice here would be an example program together with -@c an image that says more than the mythical thousand words. +@code{gfc_code} structure whose @code{next} member starts the chain of +statements inside the block; this structure's @code{op} member should be set to +the same value as the parent structure's @code{op} member. The @code{SELECT} +and @code{IF} statements may contain various blocks (the chain of @code{ELSE IF} +and @code{ELSE} blocks or the various @code{CASE}s, respectively). These chains +are linked-lists formed by the @code{block} members. + +Consider the following example code: + +@example +IF (foo < 20) THEN + PRINT *, "Too small" + foo = 20 +ELSEIF (foo > 50) THEN + PRINT *, "Too large" + foo = 50 +ELSE + PRINT *, "Good" +END IF +@end example + +This statement-block will be represented in the internal gfortran tree as +follows, were the horizontal link-chains are those induced by the @code{next} +members and vertical links down are those of @code{block}. @samp{==|} and +@samp{--|} mean @code{NULL} pointers to mark the end of a chain: + +@example +... ==> IF ==> ... + | + +--> IF foo < 20 ==> PRINT *, "Too small" ==> foo = 20 ==| + | + +--> IF foo > 50 ==> PRINT *, "Too large" ==> foo = 50 ==| + | + +--> ELSE ==> PRINT *, "Good" ==| + | + +--| +@end example + + +@subsection IF Blocks + +Conditionals are represented by @code{gfc_code} structures with their +@code{op} member set to @code{EXEC_IF}. This structure's @code{block} +member must point to another @code{gfc_code} node that is the header of the +if-block. This header's @code{op} member must be set to @code{EXEC_IF}, too, +its @code{expr} member holds the condition to check for, and its @code{next} +should point to the code-chain of the statements to execute if the condition is +true. + +If in addition an @code{ELSEIF} or @code{ELSE} block is present, the +@code{block} member of the if-block-header node points to yet another +@code{gfc_code} structure that is the header of the elseif- or else-block. Its +structure is identical to that of the if-block-header, except that in case of an +@code{ELSE} block without a new condition the @code{expr} member should be +@code{NULL}. This block can itself have its @code{block} member point to the +next @code{ELSEIF} or @code{ELSE} block if there's a chain of them. + + +@subsection Loops + +@code{DO} loops are stored in the tree as @code{gfc_code} nodes with their +@code{op} set to @code{EXEC_DO} for a @code{DO} loop with iterator variable and +to @code{EXEC_DO_WHILE} for infinite @code{DO}s and @code{DO WHILE} blocks. +Their @code{block} member should point to a @code{gfc_code} structure heading +the code-chain of the loop body; its @code{op} member should be set to +@code{EXEC_DO} or @code{EXEC_DO_WHILE}, too, respectively. + +For @code{DO WHILE} loops, the loop condition is stored on the top +@code{gfc_code} structure's @code{expr} member; @code{DO} forever loops are +simply @code{DO WHILE} loops with a constant @code{.TRUE.} loop condition in +the internal representation. + +Similarly, @code{DO} loops with an iterator have instead of the condition their +@code{ext.iterator} member set to the correct values for the loop iterator +variable and its range. + + +@subsection @code{SELECT} Statements + +A @code{SELECT} block is introduced by a @code{gfc_code} structure with an +@code{op} member of @code{EXEC_SELECT} and @code{expr} containing the expression +to evaluate and test. Its @code{block} member starts a list of @code{gfc_code} +structures linked together by their @code{block} members that stores the various +@code{CASE} parts. + +Each @code{CASE} node has its @code{op} member set to @code{EXEC_SELECT}, too, +its @code{next} member points to the code-chain to be executed in the current +case-block, and @code{extx.case_list} contains the case-values this block +corresponds to. The @code{block} member links to the next case in the list. @c --------------------------------------------------------------------- diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index 0879f52d7df..445b4a7d1a9 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -156,8 +156,9 @@ and warnings}. @item Runtime Options @xref{Runtime Options,,Options for influencing runtime behavior}. -@gccoptlist{-fconvert=@var{conversion} -frecord-marker=@var{length} @gol --fmax-subrecord-length=@var{length} -fsign-zero} +@gccoptlist{-fconvert=@var{conversion} -fno-range-check +-frecord-marker=@var{length} @gol -fmax-subrecord-length=@var{length} +-fsign-zero} @item Code Generation Options @xref{Code Gen Options,,Options for code generation conventions}. @@ -938,6 +939,16 @@ representation for unformatted files. The @code{CONVERT} specifier and the GFORTRAN_CONVERT_UNIT environment variable override the default specified by @option{-fconvert}.} + +@item -fno-range-check +@opindex @code{-fno-range-check} +Disable range checking of input values during integer @code{READ} operations. +For example, GNU Fortran will give an error if an input value is +outside of the relevant range of [@code{-HUGE()}:@code{HUGE()}]. In other words, +with @code{INTEGER (kind=4) :: i} , attempting to read @math{-2147483648} will +give an error unless @option{-fno-range-check} is given. + + @item -frecord-marker=@var{length} @opindex @code{frecord-marker=}@var{length} Specify the length of record markers for unformatted files. diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c index acbf5becff0..a1e7622a866 100644 --- a/gcc/fortran/iresolve.c +++ b/gcc/fortran/iresolve.c @@ -1341,6 +1341,34 @@ gfc_resolve_matmul (gfc_expr *f, gfc_expr *a, gfc_expr *b) f->rank = (a->rank == 2 && b->rank == 2) ? 2 : 1; + if (a->rank == 2 && b->rank == 2) + { + if (a->shape && b->shape) + { + f->shape = gfc_get_shape (f->rank); + mpz_init_set (f->shape[0], a->shape[0]); + mpz_init_set (f->shape[1], b->shape[1]); + } + } + else if (a->rank == 1) + { + if (b->shape) + { + f->shape = gfc_get_shape (f->rank); + mpz_init_set (f->shape[0], b->shape[1]); + } + } + else + { + /* b->rank == 1 and a->rank == 2 here, all other cases have + been caught in check.c. */ + if (a->shape) + { + f->shape = gfc_get_shape (f->rank); + mpz_init_set (f->shape[0], a->shape[0]); + } + } + f->value.function.name = gfc_get_string (PREFIX ("matmul_%c%d"), gfc_type_letter (f->ts.type), f->ts.kind); |
