Summary: | attribute declaration outside of INTERFACE body | ||
---|---|---|---|
Product: | gcc | Reporter: | janus |
Component: | fortran | Assignee: | janus |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | burnus, gcc-bugs |
Priority: | P3 | Keywords: | accepts-invalid |
Version: | 4.4.0 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2008-05-29 20:06:26 |
Description
janus
2008-05-28 22:17:37 UTC
Similarly for: interface function bar() real bar(:) ! wrong w/o allocatable end function bar end interface ALLOCATABLE :: bar ! <<<< WRONG end A related problem also occurs with the POINTER attribute: interface real function bar() end function bar end interface pointer :: bar Here I'm not really sure if it is forbidden, because one could interpret this as a procedure pointer. g95 gives the same error message as with DIMENSION (see above). Assuming it is not forbidden, one would still have to distinguish it from: interface function bar() real, pointer :: bar end function bar end interface This code clearly is valid (declaring a pointer-valued function). > A related problem also occurs with the POINTER attribute: > interface > real function bar() > end function bar > end interface > pointer :: bar This allowed and means a procedure pointer. See "5.1.2.6 EXTERNAL attribute" "A procedure that has both the EXTERNAL and POINTER attributes is a procedure pointer." While the following is a function (no proc pointer) with a pointer-valued return variable: > interface > function bar() > real, pointer :: bar > end function bar > end interface Here is a first attempt to fix this. The following patch should cope with the original test case and the one in comment #1. The fix for the POINTER issues will go into my procedure pointer patch. Any other attributes we need to handle? Index: gcc/fortran/symbol.c =================================================================== --- gcc/fortran/symbol.c (revision 136137) +++ gcc/fortran/symbol.c (working copy) @@ -814,6 +814,14 @@ gfc_add_allocatable (symbol_attribute *a return FAILURE; } + if (attr->flavor == FL_PROCEDURE && attr->if_source == IFSRC_IFBODY + && gfc_find_state (COMP_INTERFACE) == FAILURE) + { + gfc_error ("Attribute ALLOCATABLE declared outside of INTERFACE " + "body at %L", where); + return FAILURE; + } + attr->allocatable = 1; return check_conflict (attr, NULL, where); } @@ -832,6 +840,14 @@ gfc_add_dimension (symbol_attribute *att return FAILURE; } + if (attr->flavor == FL_PROCEDURE && attr->if_source == IFSRC_IFBODY + && gfc_find_state (COMP_INTERFACE) == FAILURE) + { + gfc_error ("Attribute DIMENSION of %s declared outside of INTERFACE " + "body at %L", name, where); + return FAILURE; + } + attr->dimension = 1; return check_conflict (attr, name, where); } @@ -1453,6 +1469,13 @@ gfc_add_explicit_interface (gfc_symbol * return FAILURE; } + if (source == IFSRC_IFBODY && (sym->attr.dimension || sym->attr.allocatable)) + { + gfc_error ("Attribute declared outside of INTERFACE body for %s at %L", + sym->name, where); + return FAILURE; + } + sym->formal = formal; sym->attr.if_source = source; Index: gcc/fortran/parse.c =================================================================== --- gcc/fortran/parse.c (revision 136137) +++ gcc/fortran/parse.c (working copy) @@ -1915,8 +1915,13 @@ loop: case ST_SUBROUTINE: new_state = COMP_SUBROUTINE; - gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY, - gfc_new_block->formal, NULL); + if (gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY, + gfc_new_block->formal, NULL) == FAILURE) + { + reject_statement (); + gfc_free_namespace (gfc_current_ns); + goto loop; + } if (current_interface.type != INTERFACE_ABSTRACT && !gfc_new_block->attr.dummy && gfc_add_external (&gfc_new_block->attr, &gfc_current_locus) == FAILURE) @@ -1929,8 +1934,13 @@ loop: case ST_FUNCTION: new_state = COMP_FUNCTION; - gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY, - gfc_new_block->formal, NULL); + if (gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY, + gfc_new_block->formal, NULL) == FAILURE) + { + reject_statement (); + gfc_free_namespace (gfc_current_ns); + goto loop; + } if (current_interface.type != INTERFACE_ABSTRACT && !gfc_new_block->attr.dummy && gfc_add_external (&gfc_new_block->attr, &gfc_current_locus) == FAILURE) > Any other attributes we need to handle?
I think that's all. I looked through the list of attributes and most are not possible for procedures or are already rejected. Thus I think we have all.
Subject: Bug 36361 Author: janus Date: Mon Jun 2 21:50:23 2008 New Revision: 136296 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=136296 Log: 2008-06-02 Janus Weil <janus@gcc.gnu.org> PR fortran/36361 * symbol.c (gfc_add_allocatable,gfc_add_dimension, gfc_add_explicit_interface): Added checks. * decl.c (attr_decl1): Added missing "var_locus". * parse.c (parse_interface): Checking for errors. 2008-06-02 Janus Weil <janus@gcc.gnu.org> PR fortran/36361 * gfortran.dg/interface_24.f90: New. Added: trunk/gcc/testsuite/gfortran.dg/interface_24.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/decl.c trunk/gcc/fortran/parse.c trunk/gcc/fortran/symbol.c trunk/gcc/testsuite/ChangeLog |