mirror of git://gcc.gnu.org/git/gcc.git
gfortran.h (gfc_find_component): Add new arguments.
2008-08-25 Daniel Kraft <d@domob.eu> * gfortran.h (gfc_find_component): Add new arguments. * parse.c (parse_derived_contains): Check if the derived-type containing the CONTAINS section is SEQUENCE/BIND(C). * resolve.c (resolve_typebound_procedure): Check for name collision with components. (resolve_fl_derived): Check for name collision with inherited type-bound procedures. * symbol.c (gfc_find_component): New arguments `noaccess' and `silent'. (gfc_add_component): Adapt for new arguments. * primary.c (match_varspec), (gfc_match_structure_constructor): Ditto. 2008-08-25 Daniel Kraft <d@domob.eu> * gfortran.dg/extends_7.f03: New test. * gfortran.dg/typebound_proc_7.f03: New test. * gfortran.dg/typebound_proc_8.f03: New test. From-SVN: r139566
This commit is contained in:
parent
e02aa5ec86
commit
9d1210f47f
|
|
@ -1,3 +1,16 @@
|
||||||
|
2008-08-25 Daniel Kraft <d@domob.eu>
|
||||||
|
|
||||||
|
* gfortran.h (gfc_find_component): Add new arguments.
|
||||||
|
* parse.c (parse_derived_contains): Check if the derived-type containing
|
||||||
|
the CONTAINS section is SEQUENCE/BIND(C).
|
||||||
|
* resolve.c (resolve_typebound_procedure): Check for name collision with
|
||||||
|
components.
|
||||||
|
(resolve_fl_derived): Check for name collision with inherited
|
||||||
|
type-bound procedures.
|
||||||
|
* symbol.c (gfc_find_component): New arguments `noaccess' and `silent'.
|
||||||
|
(gfc_add_component): Adapt for new arguments.
|
||||||
|
* primary.c (match_varspec), (gfc_match_structure_constructor): Ditto.
|
||||||
|
|
||||||
2008-08-24 Tobias Burnus <burnus@net-b.de>
|
2008-08-24 Tobias Burnus <burnus@net-b.de>
|
||||||
|
|
||||||
PR fortran/37201
|
PR fortran/37201
|
||||||
|
|
|
||||||
|
|
@ -2208,7 +2208,7 @@ gfc_try gfc_copy_attr (symbol_attribute *, symbol_attribute *, locus *);
|
||||||
gfc_try gfc_add_component (gfc_symbol *, const char *, gfc_component **);
|
gfc_try gfc_add_component (gfc_symbol *, const char *, gfc_component **);
|
||||||
gfc_symbol *gfc_use_derived (gfc_symbol *);
|
gfc_symbol *gfc_use_derived (gfc_symbol *);
|
||||||
gfc_symtree *gfc_use_derived_tree (gfc_symtree *);
|
gfc_symtree *gfc_use_derived_tree (gfc_symtree *);
|
||||||
gfc_component *gfc_find_component (gfc_symbol *, const char *);
|
gfc_component *gfc_find_component (gfc_symbol *, const char *, bool, bool);
|
||||||
|
|
||||||
gfc_st_label *gfc_get_st_label (int);
|
gfc_st_label *gfc_get_st_label (int);
|
||||||
void gfc_free_st_label (gfc_st_label *);
|
void gfc_free_st_label (gfc_st_label *);
|
||||||
|
|
|
||||||
|
|
@ -1715,8 +1715,19 @@ parse_derived_contains (void)
|
||||||
bool error_flag = false;
|
bool error_flag = false;
|
||||||
bool to_finish;
|
bool to_finish;
|
||||||
|
|
||||||
accept_statement (ST_CONTAINS);
|
|
||||||
gcc_assert (gfc_current_state () == COMP_DERIVED);
|
gcc_assert (gfc_current_state () == COMP_DERIVED);
|
||||||
|
gcc_assert (gfc_current_block ());
|
||||||
|
|
||||||
|
/* Derived-types with SEQUENCE and/or BIND(C) must not have a CONTAINS
|
||||||
|
section. */
|
||||||
|
if (gfc_current_block ()->attr.sequence)
|
||||||
|
gfc_error ("Derived-type '%s' with SEQUENCE must not have a CONTAINS"
|
||||||
|
" section at %C", gfc_current_block ()->name);
|
||||||
|
if (gfc_current_block ()->attr.is_bind_c)
|
||||||
|
gfc_error ("Derived-type '%s' with BIND(C) must not have a CONTAINS"
|
||||||
|
" section at %C", gfc_current_block ()->name);
|
||||||
|
|
||||||
|
accept_statement (ST_CONTAINS);
|
||||||
push_state (&s, COMP_DERIVED_CONTAINS, NULL);
|
push_state (&s, COMP_DERIVED_CONTAINS, NULL);
|
||||||
|
|
||||||
to_finish = false;
|
to_finish = false;
|
||||||
|
|
|
||||||
|
|
@ -1757,7 +1757,7 @@ match_varspec (gfc_expr *primary, int equiv_flag)
|
||||||
if (m != MATCH_YES)
|
if (m != MATCH_YES)
|
||||||
return MATCH_ERROR;
|
return MATCH_ERROR;
|
||||||
|
|
||||||
component = gfc_find_component (sym, name);
|
component = gfc_find_component (sym, name, false, false);
|
||||||
if (component == NULL)
|
if (component == NULL)
|
||||||
return MATCH_ERROR;
|
return MATCH_ERROR;
|
||||||
|
|
||||||
|
|
@ -2096,7 +2096,7 @@ gfc_match_structure_constructor (gfc_symbol *sym, gfc_expr **result, bool parent
|
||||||
|
|
||||||
where = gfc_current_locus;
|
where = gfc_current_locus;
|
||||||
|
|
||||||
gfc_find_component (sym, NULL);
|
gfc_find_component (sym, NULL, false, true);
|
||||||
|
|
||||||
/* Match the component list and store it in a list together with the
|
/* Match the component list and store it in a list together with the
|
||||||
corresponding component names. Check for empty argument list first. */
|
corresponding component names. Check for empty argument list first. */
|
||||||
|
|
@ -2149,13 +2149,15 @@ gfc_match_structure_constructor (gfc_symbol *sym, gfc_expr **result, bool parent
|
||||||
strncpy (comp_tail->name, comp->name, GFC_MAX_SYMBOL_LEN + 1);
|
strncpy (comp_tail->name, comp->name, GFC_MAX_SYMBOL_LEN + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the current component in the structure definition and check its
|
/* Find the current component in the structure definition and check
|
||||||
access is not private. */
|
its access is not private. */
|
||||||
if (comp)
|
if (comp)
|
||||||
this_comp = gfc_find_component (sym, comp->name);
|
this_comp = gfc_find_component (sym, comp->name, false, false);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this_comp = gfc_find_component (sym, (const char *)comp_tail->name);
|
this_comp = gfc_find_component (sym,
|
||||||
|
(const char *)comp_tail->name,
|
||||||
|
false, false);
|
||||||
comp = NULL; /* Reset needed! */
|
comp = NULL; /* Reset needed! */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7800,6 +7800,7 @@ resolve_typebound_procedure (gfc_symtree* stree)
|
||||||
locus where;
|
locus where;
|
||||||
gfc_symbol* me_arg;
|
gfc_symbol* me_arg;
|
||||||
gfc_symbol* super_type;
|
gfc_symbol* super_type;
|
||||||
|
gfc_component* comp;
|
||||||
|
|
||||||
/* If this is no type-bound procedure, just return. */
|
/* If this is no type-bound procedure, just return. */
|
||||||
if (!stree->typebound)
|
if (!stree->typebound)
|
||||||
|
|
@ -7898,6 +7899,25 @@ resolve_typebound_procedure (gfc_symtree* stree)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See if there's a name collision with a component directly in this type. */
|
||||||
|
for (comp = resolve_bindings_derived->components; comp; comp = comp->next)
|
||||||
|
if (!strcmp (comp->name, stree->name))
|
||||||
|
{
|
||||||
|
gfc_error ("Procedure '%s' at %L has the same name as a component of"
|
||||||
|
" '%s'",
|
||||||
|
stree->name, &where, resolve_bindings_derived->name);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to find a name collision with an inherited component. */
|
||||||
|
if (super_type && gfc_find_component (super_type, stree->name, true, true))
|
||||||
|
{
|
||||||
|
gfc_error ("Procedure '%s' at %L has the same name as an inherited"
|
||||||
|
" component of '%s'",
|
||||||
|
stree->name, &where, resolve_bindings_derived->name);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: Remove once typebound-procedures are fully implemented. */
|
/* FIXME: Remove once typebound-procedures are fully implemented. */
|
||||||
{
|
{
|
||||||
/* Output the error only once so we can do reasonable testing. */
|
/* Output the error only once so we can do reasonable testing. */
|
||||||
|
|
@ -7954,11 +7974,24 @@ add_dt_to_dt_list (gfc_symbol *derived)
|
||||||
static gfc_try
|
static gfc_try
|
||||||
resolve_fl_derived (gfc_symbol *sym)
|
resolve_fl_derived (gfc_symbol *sym)
|
||||||
{
|
{
|
||||||
|
gfc_symbol* super_type;
|
||||||
gfc_component *c;
|
gfc_component *c;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
super_type = gfc_get_derived_super_type (sym);
|
||||||
|
|
||||||
for (c = sym->components; c != NULL; c = c->next)
|
for (c = sym->components; c != NULL; c = c->next)
|
||||||
{
|
{
|
||||||
|
/* If this type is an extension, see if this component has the same name
|
||||||
|
as an inherited type-bound procedure. */
|
||||||
|
if (super_type && gfc_find_typebound_proc (super_type, c->name))
|
||||||
|
{
|
||||||
|
gfc_error ("Component '%s' of '%s' at %L has the same name as an"
|
||||||
|
" inherited type-bound procedure",
|
||||||
|
c->name, sym->name, &c->loc);
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (c->ts.type == BT_CHARACTER)
|
if (c->ts.type == BT_CHARACTER)
|
||||||
{
|
{
|
||||||
if (c->ts.cl->length == NULL
|
if (c->ts.cl->length == NULL
|
||||||
|
|
|
||||||
|
|
@ -1722,7 +1722,7 @@ gfc_add_component (gfc_symbol *sym, const char *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym->attr.extension
|
if (sym->attr.extension
|
||||||
&& gfc_find_component (sym->components->ts.derived, name))
|
&& gfc_find_component (sym->components->ts.derived, name, true, true))
|
||||||
{
|
{
|
||||||
gfc_error ("Component '%s' at %C already in the parent type "
|
gfc_error ("Component '%s' at %C already in the parent type "
|
||||||
"at %L", name, &sym->components->ts.derived->declared_at);
|
"at %L", name, &sym->components->ts.derived->declared_at);
|
||||||
|
|
@ -1839,10 +1839,12 @@ bad:
|
||||||
|
|
||||||
/* Given a derived type node and a component name, try to locate the
|
/* Given a derived type node and a component name, try to locate the
|
||||||
component structure. Returns the NULL pointer if the component is
|
component structure. Returns the NULL pointer if the component is
|
||||||
not found or the components are private. */
|
not found or the components are private. If noaccess is set, no access
|
||||||
|
checks are done. */
|
||||||
|
|
||||||
gfc_component *
|
gfc_component *
|
||||||
gfc_find_component (gfc_symbol *sym, const char *name)
|
gfc_find_component (gfc_symbol *sym, const char *name,
|
||||||
|
bool noaccess, bool silent)
|
||||||
{
|
{
|
||||||
gfc_component *p;
|
gfc_component *p;
|
||||||
|
|
||||||
|
|
@ -1862,22 +1864,24 @@ gfc_find_component (gfc_symbol *sym, const char *name)
|
||||||
&& sym->attr.extension
|
&& sym->attr.extension
|
||||||
&& sym->components->ts.type == BT_DERIVED)
|
&& sym->components->ts.type == BT_DERIVED)
|
||||||
{
|
{
|
||||||
p = gfc_find_component (sym->components->ts.derived, name);
|
p = gfc_find_component (sym->components->ts.derived, name,
|
||||||
|
noaccess, silent);
|
||||||
/* Do not overwrite the error. */
|
/* Do not overwrite the error. */
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p == NULL)
|
if (p == NULL && !silent)
|
||||||
gfc_error ("'%s' at %C is not a member of the '%s' structure",
|
gfc_error ("'%s' at %C is not a member of the '%s' structure",
|
||||||
name, sym->name);
|
name, sym->name);
|
||||||
|
|
||||||
else if (sym->attr.use_assoc)
|
else if (sym->attr.use_assoc && !noaccess)
|
||||||
{
|
{
|
||||||
if (p->attr.access == ACCESS_PRIVATE)
|
if (p->attr.access == ACCESS_PRIVATE)
|
||||||
{
|
{
|
||||||
gfc_error ("Component '%s' at %C is a PRIVATE component of '%s'",
|
if (!silent)
|
||||||
name, sym->name);
|
gfc_error ("Component '%s' at %C is a PRIVATE component of '%s'",
|
||||||
|
name, sym->name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1885,8 +1889,9 @@ gfc_find_component (gfc_symbol *sym, const char *name)
|
||||||
out at this place. */
|
out at this place. */
|
||||||
if (p->attr.access != ACCESS_PUBLIC && sym->component_access == ACCESS_PRIVATE)
|
if (p->attr.access != ACCESS_PUBLIC && sym->component_access == ACCESS_PRIVATE)
|
||||||
{
|
{
|
||||||
gfc_error ("All components of '%s' are PRIVATE in structure"
|
if (!silent)
|
||||||
" constructor at %C", sym->name);
|
gfc_error ("All components of '%s' are PRIVATE in structure"
|
||||||
|
" constructor at %C", sym->name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
2008-08-25 Daniel Kraft <d@domob.eu>
|
||||||
|
|
||||||
|
* gfortran.dg/extends_7.f03: New test.
|
||||||
|
* gfortran.dg/typebound_proc_7.f03: New test.
|
||||||
|
* gfortran.dg/typebound_proc_8.f03: New test.
|
||||||
|
|
||||||
2008-08-24 Adam Nemet <anemet@caviumnetworks.com>
|
2008-08-24 Adam Nemet <anemet@caviumnetworks.com>
|
||||||
|
|
||||||
* gcc.target/mips/octeon-pop-1.c: New test.
|
* gcc.target/mips/octeon-pop-1.c: New test.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
! { dg-do compile }
|
||||||
|
! Check for re-definition of inherited components in the sub-type.
|
||||||
|
|
||||||
|
MODULE m1
|
||||||
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
TYPE supert
|
||||||
|
INTEGER :: c1
|
||||||
|
INTEGER, PRIVATE :: c2
|
||||||
|
END TYPE supert
|
||||||
|
|
||||||
|
END MODULE m1
|
||||||
|
|
||||||
|
MODULE m2
|
||||||
|
USE m1 ! { dg-error "already in the parent type" }
|
||||||
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
TYPE, EXTENDS(supert) :: subt
|
||||||
|
INTEGER :: c1 ! { dg-error "already in the parent type" }
|
||||||
|
INTEGER :: c2 ! { dg-error "already in the parent type" }
|
||||||
|
END TYPE subt
|
||||||
|
|
||||||
|
END MODULE m2
|
||||||
|
|
||||||
|
! { dg-final { cleanup-modules "m1 m2" } }
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
! { dg-do compile }
|
||||||
|
|
||||||
|
! Type-bound procedures
|
||||||
|
! Tests that SEQUENCE and BIND(C) types do not allow a type-bound procedure
|
||||||
|
! section.
|
||||||
|
|
||||||
|
MODULE testmod
|
||||||
|
USE ISO_C_BINDING
|
||||||
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
TYPE sequencet
|
||||||
|
SEQUENCE
|
||||||
|
INTEGER :: a, b
|
||||||
|
CONTAINS ! { dg-error "SEQUENCE" }
|
||||||
|
PROCEDURE, NOPASS :: proc_noarg
|
||||||
|
END TYPE sequencet
|
||||||
|
|
||||||
|
TYPE, BIND(C) :: bindct
|
||||||
|
INTEGER(c_int) :: a
|
||||||
|
REAL(c_float) :: b
|
||||||
|
CONTAINS ! { dg-error "BIND" }
|
||||||
|
PROCEDURE, NOPASS :: proc_noarg
|
||||||
|
END TYPE bindct
|
||||||
|
|
||||||
|
CONTAINS
|
||||||
|
|
||||||
|
SUBROUTINE proc_noarg ()
|
||||||
|
END SUBROUTINE proc_noarg
|
||||||
|
|
||||||
|
END MODULE testmod
|
||||||
|
|
||||||
|
! { dg-final { cleanup-modules "testmod" } }
|
||||||
|
! FIXME: Remove not-yet-implemented error when implemented.
|
||||||
|
! { dg-excess-errors "not yet implemented" }
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
! { dg-do compile }
|
||||||
|
|
||||||
|
! Type-bound procedures
|
||||||
|
! Test for name collision between type-bound procedures and components.
|
||||||
|
|
||||||
|
MODULE testmod
|
||||||
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
TYPE t
|
||||||
|
REAL :: comp
|
||||||
|
CONTAINS
|
||||||
|
PROCEDURE, NOPASS :: comp => proc ! { dg-error "same name as a component" }
|
||||||
|
END TYPE t
|
||||||
|
|
||||||
|
TYPE supert
|
||||||
|
INTEGER :: comp1
|
||||||
|
CONTAINS
|
||||||
|
PROCEDURE, NOPASS :: comp2 => proc
|
||||||
|
END TYPE supert
|
||||||
|
|
||||||
|
TYPE, EXTENDS(supert) :: subt1
|
||||||
|
INTEGER :: comp2 ! { dg-error "same name" }
|
||||||
|
END TYPE subt1
|
||||||
|
|
||||||
|
TYPE, EXTENDS(supert) :: subt2
|
||||||
|
CONTAINS
|
||||||
|
PROCEDURE, NOPASS :: comp1 => proc ! { dg-error "same name as an inherited component" }
|
||||||
|
END TYPE subt2
|
||||||
|
|
||||||
|
CONTAINS
|
||||||
|
|
||||||
|
SUBROUTINE proc ()
|
||||||
|
END SUBROUTINE proc
|
||||||
|
|
||||||
|
END MODULE testmod
|
||||||
|
|
||||||
|
! { dg-final { cleanup-modules "testmod" } }
|
||||||
|
! FIXME: Remove not-yet-implemented error when implemented.
|
||||||
|
! { dg-excess-errors "not yet implemented" }
|
||||||
Loading…
Reference in New Issue