Commit e62532af by Janus Weil

re PR fortran/36361 (attribute declaration outside of INTERFACE body)

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.

From-SVN: r136296
parent 80d7287f
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 Daniel Kraft <d@domob.eu> 2008-06-02 Daniel Kraft <d@domob.eu>
* gfortran.h: New statement-type ST_FINAL for FINAL declarations. * gfortran.h: New statement-type ST_FINAL for FINAL declarations.
......
...@@ -5216,7 +5216,7 @@ attr_decl1 (void) ...@@ -5216,7 +5216,7 @@ attr_decl1 (void)
/* Update symbol table. DIMENSION attribute is set /* Update symbol table. DIMENSION attribute is set
in gfc_set_array_spec(). */ in gfc_set_array_spec(). */
if (current_attr.dimension == 0 if (current_attr.dimension == 0
&& gfc_copy_attr (&sym->attr, &current_attr, NULL) == FAILURE) && gfc_copy_attr (&sym->attr, &current_attr, &var_locus) == FAILURE)
{ {
m = MATCH_ERROR; m = MATCH_ERROR;
goto cleanup; goto cleanup;
......
...@@ -1974,23 +1974,18 @@ loop: ...@@ -1974,23 +1974,18 @@ loop:
unexpected_eof (); unexpected_eof ();
case ST_SUBROUTINE: case ST_SUBROUTINE:
new_state = COMP_SUBROUTINE; case ST_FUNCTION:
gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY, if (st == ST_SUBROUTINE)
gfc_new_block->formal, NULL); new_state = COMP_SUBROUTINE;
if (current_interface.type != INTERFACE_ABSTRACT && else if (st == ST_FUNCTION)
!gfc_new_block->attr.dummy && new_state = COMP_FUNCTION;
gfc_add_external (&gfc_new_block->attr, &gfc_current_locus) == FAILURE) if (gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY,
gfc_new_block->formal, NULL) == FAILURE)
{ {
reject_statement (); reject_statement ();
gfc_free_namespace (gfc_current_ns); gfc_free_namespace (gfc_current_ns);
goto loop; goto loop;
} }
break;
case ST_FUNCTION:
new_state = COMP_FUNCTION;
gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY,
gfc_new_block->formal, NULL);
if (current_interface.type != INTERFACE_ABSTRACT && if (current_interface.type != INTERFACE_ABSTRACT &&
!gfc_new_block->attr.dummy && !gfc_new_block->attr.dummy &&
gfc_add_external (&gfc_new_block->attr, &gfc_current_locus) == FAILURE) gfc_add_external (&gfc_new_block->attr, &gfc_current_locus) == FAILURE)
......
...@@ -814,6 +814,14 @@ gfc_add_allocatable (symbol_attribute *attr, locus *where) ...@@ -814,6 +814,14 @@ gfc_add_allocatable (symbol_attribute *attr, locus *where)
return FAILURE; return FAILURE;
} }
if (attr->flavor == FL_PROCEDURE && attr->if_source == IFSRC_IFBODY
&& gfc_find_state (COMP_INTERFACE) == FAILURE)
{
gfc_error ("ALLOCATABLE specified outside of INTERFACE body at %L",
where);
return FAILURE;
}
attr->allocatable = 1; attr->allocatable = 1;
return check_conflict (attr, NULL, where); return check_conflict (attr, NULL, where);
} }
...@@ -832,6 +840,14 @@ gfc_add_dimension (symbol_attribute *attr, const char *name, locus *where) ...@@ -832,6 +840,14 @@ gfc_add_dimension (symbol_attribute *attr, const char *name, locus *where)
return FAILURE; return FAILURE;
} }
if (attr->flavor == FL_PROCEDURE && attr->if_source == IFSRC_IFBODY
&& gfc_find_state (COMP_INTERFACE) == FAILURE)
{
gfc_error ("DIMENSION specified for '%s' outside its INTERFACE body "
"at %L", name, where);
return FAILURE;
}
attr->dimension = 1; attr->dimension = 1;
return check_conflict (attr, name, where); return check_conflict (attr, name, where);
} }
...@@ -1453,6 +1469,13 @@ gfc_add_explicit_interface (gfc_symbol *sym, ifsrc source, ...@@ -1453,6 +1469,13 @@ gfc_add_explicit_interface (gfc_symbol *sym, ifsrc source,
return FAILURE; return FAILURE;
} }
if (source == IFSRC_IFBODY && (sym->attr.dimension || sym->attr.allocatable))
{
gfc_error ("'%s' at %L has attributes specified outside its INTERFACE "
"body", sym->name, where);
return FAILURE;
}
sym->formal = formal; sym->formal = formal;
sym->attr.if_source = source; sym->attr.if_source = source;
......
2008-06-02 Janus Weil <janus@gcc.gnu.org>
PR fortran/36361
* gfortran.dg/interface_24.f90: New.
2008-06-02 Paolo Carlini <paolo.carlini@oracle.com> 2008-06-02 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/36404 PR c++/36404
......
! { dg-do compile }
!
! This tests the fix for PR36361: If a function was declared in an INTERFACE
! statement, no attributes may be declared outside of the INTERFACE body.
!
! Contributed by Janus Weil <janus@gcc.gnu.org>
module m1
interface
real function f1()
end function
end interface
dimension :: f1(4) ! { dg-error "outside its INTERFACE body" }
end module
module m2
dimension :: f2(4)
interface
real function f2() ! { dg-error "outside its INTERFACE body" }
!end function
end interface
end module
! valid
module m3
interface
real function f3()
dimension :: f3(4)
end function
end interface
end module
module m4
interface
function f4() ! { dg-error "cannot have a deferred shape" }
real :: f4(:)
end function
end interface
allocatable :: f4 ! { dg-error "outside of INTERFACE body" }
end module
module m5
allocatable :: f5(:)
interface
function f5() ! { dg-error "outside its INTERFACE body" }
!real f5(:)
!end function
end interface
end module
!valid
module m6
interface
function f6()
real f6(:)
allocatable :: f6
end function
end interface
end module
! { dg-final { cleanup-modules "m1 m2 m3 m4 m5 m6" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment