summaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog24
-rw-r--r--gcc/fortran/gfc-internals.texi101
-rw-r--r--gcc/fortran/invoke.texi15
-rw-r--r--gcc/fortran/iresolve.c28
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);