aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kraft <d@domob.eu>2008-08-25 19:58:53 +0200
committerDaniel Kraft <domob@gcc.gnu.org>2008-08-25 19:58:53 +0200
commit9d1210f47f50fa5a1e397632792aa97668e56e0e (patch)
tree48f2f28391f6447501ac0481370dfd5b4e376e7c
parente02aa5ec860b71931d3223505e0337ffb5d1a7a4 (diff)
downloadgcc-9d1210f47f50fa5a1e397632792aa97668e56e0e.zip
gcc-9d1210f47f50fa5a1e397632792aa97668e56e0e.tar.gz
gcc-9d1210f47f50fa5a1e397632792aa97668e56e0e.tar.bz2
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
-rw-r--r--gcc/fortran/ChangeLog13
-rw-r--r--gcc/fortran/gfortran.h2
-rw-r--r--gcc/fortran/parse.c13
-rw-r--r--gcc/fortran/primary.c14
-rw-r--r--gcc/fortran/resolve.c33
-rw-r--r--gcc/fortran/symbol.c25
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gfortran.dg/extends_7.f0325
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_proc_7.f0334
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_proc_8.f0339
10 files changed, 186 insertions, 18 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 8c8c679..b606361 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -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>
PR fortran/37201
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 322b4a5..b063474 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -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_symbol *gfc_use_derived (gfc_symbol *);
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);
void gfc_free_st_label (gfc_st_label *);
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 4bf1b81..f12afd5 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -1715,8 +1715,19 @@ parse_derived_contains (void)
bool error_flag = false;
bool to_finish;
- accept_statement (ST_CONTAINS);
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);
to_finish = false;
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index 4865b75..5d73407 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -1757,7 +1757,7 @@ match_varspec (gfc_expr *primary, int equiv_flag)
if (m != MATCH_YES)
return MATCH_ERROR;
- component = gfc_find_component (sym, name);
+ component = gfc_find_component (sym, name, false, false);
if (component == NULL)
return MATCH_ERROR;
@@ -2096,7 +2096,7 @@ gfc_match_structure_constructor (gfc_symbol *sym, gfc_expr **result, bool parent
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
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);
}
- /* Find the current component in the structure definition and check its
- access is not private. */
+ /* Find the current component in the structure definition and check
+ its access is not private. */
if (comp)
- this_comp = gfc_find_component (sym, comp->name);
+ this_comp = gfc_find_component (sym, comp->name, false, false);
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! */
}
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 9cde435..6bf5380 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -7800,6 +7800,7 @@ resolve_typebound_procedure (gfc_symtree* stree)
locus where;
gfc_symbol* me_arg;
gfc_symbol* super_type;
+ gfc_component* comp;
/* If this is no type-bound procedure, just return. */
if (!stree->typebound)
@@ -7898,6 +7899,25 @@ resolve_typebound_procedure (gfc_symtree* stree)
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. */
{
/* 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
resolve_fl_derived (gfc_symbol *sym)
{
+ gfc_symbol* super_type;
gfc_component *c;
int i;
+ super_type = gfc_get_derived_super_type (sym);
+
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.cl->length == NULL
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 005086d..2eed9fe 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -1722,7 +1722,7 @@ gfc_add_component (gfc_symbol *sym, const char *name,
}
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 "
"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
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_find_component (gfc_symbol *sym, const char *name)
+gfc_find_component (gfc_symbol *sym, const char *name,
+ bool noaccess, bool silent)
{
gfc_component *p;
@@ -1862,22 +1864,24 @@ gfc_find_component (gfc_symbol *sym, const char *name)
&& sym->attr.extension
&& 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. */
if (p == NULL)
return p;
}
- if (p == NULL)
+ if (p == NULL && !silent)
gfc_error ("'%s' at %C is not a member of the '%s' structure",
name, sym->name);
- else if (sym->attr.use_assoc)
+ else if (sym->attr.use_assoc && !noaccess)
{
if (p->attr.access == ACCESS_PRIVATE)
{
- gfc_error ("Component '%s' at %C is a PRIVATE component of '%s'",
- name, sym->name);
+ if (!silent)
+ gfc_error ("Component '%s' at %C is a PRIVATE component of '%s'",
+ name, sym->name);
return NULL;
}
@@ -1885,8 +1889,9 @@ gfc_find_component (gfc_symbol *sym, const char *name)
out at this place. */
if (p->attr.access != ACCESS_PUBLIC && sym->component_access == ACCESS_PRIVATE)
{
- gfc_error ("All components of '%s' are PRIVATE in structure"
- " constructor at %C", sym->name);
+ if (!silent)
+ gfc_error ("All components of '%s' are PRIVATE in structure"
+ " constructor at %C", sym->name);
return NULL;
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1604c3b..4406270 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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>
* gcc.target/mips/octeon-pop-1.c: New test.
diff --git a/gcc/testsuite/gfortran.dg/extends_7.f03 b/gcc/testsuite/gfortran.dg/extends_7.f03
new file mode 100644
index 0000000..ebb2fcc3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/extends_7.f03
@@ -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" } }
diff --git a/gcc/testsuite/gfortran.dg/typebound_proc_7.f03 b/gcc/testsuite/gfortran.dg/typebound_proc_7.f03
new file mode 100644
index 0000000..a12b1d2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/typebound_proc_7.f03
@@ -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" }
diff --git a/gcc/testsuite/gfortran.dg/typebound_proc_8.f03 b/gcc/testsuite/gfortran.dg/typebound_proc_8.f03
new file mode 100644
index 0000000..087b11f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/typebound_proc_8.f03
@@ -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" }