[multiple changes]

2007-08-18  Paul Thomas  <pault@gcc.gnu.org>
	    Janus Weil  <jaydub66@gmail.com>

	* interface.c (gfc_match_interface,gfc_match_abstract_interface,
	gfc_match_end_interface,gfc_add_interface): Add abstract interface.
	* dump-parse-tree.c (gfc_show_attr): Ditto.
	* gfortran.h (interface_type,symbol_attribute): Ditto.
	* module.c (gfc_match_use,ab_attribute,attr_bits,
	mio_symbol_attribute): Ditto.
	* resolve.c (resolve_function): Ditto.
	* match.h: Ditto.
	* parse.c (decode_statement): Ditto.
	(parse_interface): Ditto, check for C1203 (name of abstract interface
	cannot be the same as an intrinsic type).
	* decl.c (gfc_match_bind_c): Check for NAME= with abstract interfaces.
	(access_attr_decl): Handle Abstract interfaces.


2007-08-17  Tobias Burnus  <burnus@net-b.de>

	* gfortran.dg/interface_abstract_1.f90: New.

From-SVN: r127612
This commit is contained in:
Tobias Burnus 2007-08-18 16:57:21 +02:00
parent a595913e95
commit 9e1d712c40
11 changed files with 109 additions and 6 deletions

View file

@ -1,3 +1,20 @@
2007-08-18 Paul Thomas <pault@gcc.gnu.org>
Janus Weil <jaydub66@gmail.com>
* interface.c (gfc_match_interface,gfc_match_abstract_interface,
gfc_match_end_interface,gfc_add_interface): Add abstract interface.
* dump-parse-tree.c (gfc_show_attr): Ditto.
* gfortran.h (interface_type,symbol_attribute): Ditto.
* module.c (gfc_match_use,ab_attribute,attr_bits,
mio_symbol_attribute): Ditto.
* resolve.c (resolve_function): Ditto.
* match.h: Ditto.
* parse.c (decode_statement): Ditto.
(parse_interface): Ditto, check for C1203 (name of abstract interface
cannot be the same as an intrinsic type).
* decl.c (gfc_match_bind_c): Check for NAME= with abstract interfaces.
(access_attr_decl): Handle Abstract interfaces.
2007-08-18 Paul Thomas <pault@gcc.gnu.org>
PR fortran/32881

View file

@ -4182,7 +4182,13 @@ gfc_match_bind_c (gfc_symbol *sym)
if (sym != NULL && sym->name != NULL && has_name_equals == 0)
strncpy (sym->binding_label, sym->name, strlen (sym->name) + 1);
}
if (has_name_equals && current_interface.type == INTERFACE_ABSTRACT)
{
gfc_error ("NAME not allowed on BIND(C) for ABSTRACT INTERFACE at %C");
return MATCH_ERROR;
}
return MATCH_YES;
}
@ -4842,6 +4848,7 @@ access_attr_decl (gfc_statement st)
switch (type)
{
case INTERFACE_NAMELESS:
case INTERFACE_ABSTRACT:
goto syntax;
case INTERFACE_GENERIC:

View file

@ -591,6 +591,8 @@ gfc_show_attr (symbol_attribute *attr)
if (attr->in_common)
gfc_status (" IN-COMMON");
if (attr->abstract)
gfc_status (" ABSTRACT INTERFACE");
if (attr->function)
gfc_status (" FUNCTION");
if (attr->subroutine)

View file

@ -260,7 +260,7 @@ gfc_statement;
typedef enum
{
INTERFACE_NAMELESS = 1, INTERFACE_GENERIC,
INTERFACE_INTRINSIC_OP, INTERFACE_USER_OP
INTERFACE_INTRINSIC_OP, INTERFACE_USER_OP, INTERFACE_ABSTRACT
}
interface_type;
@ -658,7 +658,7 @@ typedef struct
/* Function/subroutine attributes */
unsigned sequence:1, elemental:1, pure:1, recursive:1;
unsigned unmaskable:1, masked:1, contained:1, mod_proc:1;
unsigned unmaskable:1, masked:1, contained:1, mod_proc:1, abstract:1;
/* This is set if the subroutine doesn't return. Currently, this
is only possible for intrinsic subroutines. */

View file

@ -175,7 +175,8 @@ syntax:
}
/* Match one of the five forms of an interface statement. */
/* Match one of the five F95 forms of an interface statement. The
matcher for the abstract interface follows. */
match
gfc_match_interface (void)
@ -232,6 +233,7 @@ gfc_match_interface (void)
break;
case INTERFACE_NAMELESS:
case INTERFACE_ABSTRACT:
break;
}
@ -239,6 +241,32 @@ gfc_match_interface (void)
}
/* Match a F2003 abstract interface. */
match
gfc_match_abstract_interface (void)
{
match m;
if (gfc_notify_std (GFC_STD_F2003, "Fortran 2003: ABSTRACT INTERFACE at %C")
== FAILURE)
return MATCH_ERROR;
m = gfc_match_eos ();
if (m != MATCH_YES)
{
gfc_error ("Syntax error in ABSTRACT INTERFACE statement at %C");
return MATCH_ERROR;
}
current_interface.type = INTERFACE_ABSTRACT;
return m;
}
/* Match the different sort of generic-specs that can be present after
the END INTERFACE itself. */
@ -270,7 +298,8 @@ gfc_match_end_interface (void)
switch (current_interface.type)
{
case INTERFACE_NAMELESS:
if (type != current_interface.type)
case INTERFACE_ABSTRACT:
if (type != INTERFACE_NAMELESS)
{
gfc_error ("Expected a nameless interface at %C");
m = MATCH_ERROR;
@ -2449,6 +2478,7 @@ gfc_add_interface (gfc_symbol *new)
switch (current_interface.type)
{
case INTERFACE_NAMELESS:
case INTERFACE_ABSTRACT:
return SUCCESS;
case INTERFACE_INTRINSIC_OP:

View file

@ -195,6 +195,7 @@ match gfc_match_array_ref (gfc_array_ref *, gfc_array_spec *, int);
match gfc_match_array_constructor (gfc_expr **);
/* interface.c. */
match gfc_match_abstract_interface (void);
match gfc_match_generic_spec (interface_type *, char *, gfc_intrinsic_op *);
match gfc_match_interface (void);
match gfc_match_end_interface (void);

View file

@ -599,6 +599,7 @@ gfc_match_use (void)
switch (type)
{
case INTERFACE_NAMELESS:
case INTERFACE_ABSTRACT:
gfc_error ("Missing generic specification in USE statement at %C");
goto cleanup;
@ -1519,7 +1520,7 @@ typedef enum
AB_ELEMENTAL, AB_PURE, AB_RECURSIVE, AB_GENERIC, AB_ALWAYS_EXPLICIT,
AB_CRAY_POINTER, AB_CRAY_POINTEE, AB_THREADPRIVATE, AB_ALLOC_COMP,
AB_POINTER_COMP, AB_PRIVATE_COMP, AB_VALUE, AB_VOLATILE, AB_PROTECTED,
AB_IS_BIND_C, AB_IS_C_INTEROP, AB_IS_ISO_C
AB_IS_BIND_C, AB_IS_C_INTEROP, AB_IS_ISO_C, AB_ABSTRACT
}
ab_attribute;
@ -1557,6 +1558,7 @@ static const mstring attr_bits[] =
minit ("POINTER_COMP", AB_POINTER_COMP),
minit ("PRIVATE_COMP", AB_PRIVATE_COMP),
minit ("PROTECTED", AB_PROTECTED),
minit ("ABSTRACT", AB_ABSTRACT),
minit (NULL, -1)
};
@ -1639,6 +1641,8 @@ mio_symbol_attribute (symbol_attribute *attr)
MIO_NAME (ab_attribute) (AB_SUBROUTINE, attr_bits);
if (attr->generic)
MIO_NAME (ab_attribute) (AB_GENERIC, attr_bits);
if (attr->abstract)
MIO_NAME (ab_attribute) (AB_ABSTRACT, attr_bits);
if (attr->sequence)
MIO_NAME (ab_attribute) (AB_SEQUENCE, attr_bits);
@ -1739,6 +1743,9 @@ mio_symbol_attribute (symbol_attribute *attr)
case AB_GENERIC:
attr->generic = 1;
break;
case AB_ABSTRACT:
attr->abstract = 1;
break;
case AB_SEQUENCE:
attr->sequence = 1;
break;

View file

@ -172,6 +172,7 @@ decode_statement (void)
switch (c)
{
case 'a':
match ("abstract interface", gfc_match_abstract_interface, ST_INTERFACE);
match ("allocate", gfc_match_allocate, ST_ALLOCATE);
match ("allocatable", gfc_match_allocatable, ST_ATTR_DECL);
match ("assign", gfc_match_assign, ST_LABEL_ASSIGNMENT);
@ -1795,6 +1796,18 @@ loop:
}
}
if (current_interface.type == INTERFACE_ABSTRACT)
{
gfc_new_block->attr.abstract = 1;
if (!strcmp(gfc_new_block->name,"integer")
|| !strcmp(gfc_new_block->name,"real")
|| !strcmp(gfc_new_block->name,"complex")
|| !strcmp(gfc_new_block->name,"character")
|| !strcmp(gfc_new_block->name,"logical"))
gfc_error ("Name of ABSTRACT INTERFACE at %C cannot be the same as "
"an intrinsic type: %s",gfc_new_block->name);
}
push_state (&s2, new_state, gfc_new_block);
accept_statement (st);
prog_unit = gfc_new_block;

View file

@ -1968,6 +1968,13 @@ resolve_function (gfc_expr *expr)
return FAILURE;
}
if (sym && sym->attr.abstract)
{
gfc_error ("ABSTRACT INTERFACE '%s' must not be referenced at %L",
sym->name, &expr->where);
return FAILURE;
}
/* If the procedure is external, check for usage. */
if (sym && is_external_proc (sym))
resolve_global_procedure (sym, &expr->where, 0);

View file

@ -1,3 +1,7 @@
2007-08-17 Tobias Burnus <burnus@net-b.de>
* gfortran.dg/interface_abstract_1.f90: New.
2007-08-18 Paul Thomas <pault@gcc.gnu.org>
PR fortran/32881

View file

@ -0,0 +1,15 @@
! { dg-do compile }
!
implicit none
abstract interface :: one ! { dg-error "Syntax error in ABSTRACT INTERFACE statement" }
end interface ! { dg-error "Expecting END PROGRAM statement" }
abstract interface
subroutine two() bind(C)
end subroutine two
subroutine three() bind(C,name="three") ! { dg-error "NAME not allowed on BIND.C. for ABSTRACT INTERFACE" }
end subroutine three ! { dg-error "Expecting END INTERFACE statement" }
subroutine real() ! { dg-error "cannot be be the same as an intrinsic type" }
end subroutine real
end interface
end