The upcoming Fortran 2008 standard introduces the BLOCK construct which allows to declare local variables with a limited scope inside a procedure.
This is not yet implemented by gfortran. Some ideas and discussion here: http://gcc.gnu.org/ml/fortran/2009-04/msg00003.html
This feature requires a substantial re-work of symbol handling in gfortran (make it block based).
I'm not sure it needs really that much changes... After all, the semantics can probably be simulated completely via replacing the BLOCK-constructs with contained procedures that are called where the BLOCK originally was?
That's of course not a nice implementation and I do not think we should actually do this, but I believe that there needs not be that much change -- I'll work on this and try to find out a good way.
See also http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/ee95b68bf0658433#
Especially about the fine points raised by Richard Maine
For a "basically workig" (i.e. without some of the finer details and ugly corner cases, but handling all I would "reasonably" expect as user) patch, see http://gcc.gnu.org/ml/fortran/2009-09/msg00255.html.
Subject: Bug 39626
Date: Tue Sep 29 07:42:42 2009
New Revision: 152266
2009-09-29 Daniel Kraft <firstname.lastname@example.org>
* gfortran.h (enum gfc_statement): Add ST_BLOCK and ST_END_BLOCK.
(struct gfc_namespace): Convert flags to bit-fields and add flag
`construct_entities' for use with BLOCK constructs.
(enum gfc_exec_code): Add EXEC_BLOCK.
(struct gfc_code): Add namespace field to union for EXEC_BLOCK.
* match.h (gfc_match_block): New prototype.
* parse.h (enum gfc_compile_state): Add COMP_BLOCK.
* trans.h (gfc_process_block_locals): New prototype.
(gfc_trans_deferred_vars): Made public, new prototype.
* trans-stmt.h (gfc_trans_block_construct): New prototype.
* decl.c (gfc_match_end): Handle END BLOCK correctly.
(gfc_match_intent): Error if inside of BLOCK.
(gfc_match_optional), (gfc_match_value): Ditto.
* match.c (gfc_match_block): New routine.
* parse.c (decode_statement): Handle BLOCK statement.
(case_exec_markers): Add ST_BLOCK.
(case_end): Add ST_END_BLOCK.
(gfc_ascii_statement): Handle ST_BLOCK and ST_END_BLOCK.
(parse_spec): Check for statements not allowed inside of BLOCK.
(parse_block_construct): New routine.
(parse_executable): Parse BLOCKs.
(parse_progunit): Disallow CONTAINS in BLOCK constructs.
* resolve.c (is_illegal_recursion): Find real container procedure and
don't get confused by BLOCK constructs.
(resolve_block_construct): New routine.
(gfc_resolve_blocks), (resolve_code): Handle EXEC_BLOCK.
* st.c (gfc_free_statement): Handle EXEC_BLOCK statements.
* trans-decl.c (saved_local_decls): New static variable.
(add_decl_as_local): New routine.
(gfc_finish_var_decl): Add variable as local if inside BLOCK.
(gfc_trans_deferred_vars): Make public.
(gfc_process_block_locals): New routine.
* trans-stmt.c (gfc_trans_block_construct): New routine.
* trans.c (gfc_trans_code): Handle EXEC_BLOCK statements.
2009-09-29 Daniel Kraft <email@example.com>
* gfortran.dg/block_1.f08: New test.
* gfortran.dg/block_2.f08: New test.
* gfortran.dg/block_3.f90: New test.
* gfortran.dg/block_4.f08: New test.
* gfortran.dg/block_5.f08: New test.
* gfortran.dg/block_6.f08: New test.
* gfortran.dg/block_7.f08: New test.
* gfortran.dg/block_8.f08: New test.
Committed my patch linked above. This implements "basic" BLOCK support (what I as a user would reasonably expect it to behave) but misses a lot of finer details; I'll keep the PR open for those.
See my mailing list message for more information, but what I've got in mind for still missing stuff:
* handle VOLATILE and ASYNCHRONOUS as the draft standard mentions
* implement the clause requiring SAVE to not reference a common-name
* do more stuff with regards to 'construct entities' rather than "ordinary variables", for instance the IMPLICIT handling Richard Maine mentioned in his c.l.f post which is also the XFAIL'ed test-case block_7.f08
Also, Tobias mentioned (in the linked thread):
The patch looks good to me. It sometimes makes the diagnostics less
useful, e.g. for
recursive function func(i)
integer :: i, func
func = 1
func2 = func(1)
end function func
But the same "Unclassifiable statement" one gets if one not only removes
"(end )block" but also "recursive".
*** Bug 43019 has been marked as a duplicate of this bug. ***
See also http://j3-fortran.org/doc/meeting/191/10-126.txt
("Scoping unit fixes for BLOCK construct")