aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJanus Weil <janus@gcc.gnu.org>2010-06-16 14:54:54 +0200
committerJanus Weil <janus@gcc.gnu.org>2010-06-16 14:54:54 +0200
commit3e15518bc4c70b541b667e9f6bf3dfb80053b5ae (patch)
treee59b7cfa05176efde69a8f830c9e84a169966a62 /gcc
parentfe27aa8bc46f9ce5324d19e1102901639274c578 (diff)
downloadgcc-3e15518bc4c70b541b667e9f6bf3dfb80053b5ae.zip
gcc-3e15518bc4c70b541b667e9f6bf3dfb80053b5ae.tar.gz
gcc-3e15518bc4c70b541b667e9f6bf3dfb80053b5ae.tar.bz2
re PR fortran/44549 ([OOP][F2008] Type-bound procedure: bogus error from list after PROCEDURE)
2010-06-16 Janus Weil <janus@gcc.gnu.org> PR fortran/44549 * gfortran.h (gfc_get_typebound_proc): Modified Prototype. * decl.c (match_procedure_in_type): Give a unique gfc_typebound_proc structure to each procedure in a procedure list. * module.c (mio_typebound_proc): Add NULL argument to 'gfc_get_typebound_proc'. * symbol.c (gfc_get_typebound_proc): Add a new argument, which is used to initialize the new structure. 2010-06-16 Janus Weil <janus@gcc.gnu.org> PR fortran/44549 * gfortran.dg/typebound_proc_16.f03: New. From-SVN: r160834
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog11
-rw-r--r--gcc/fortran/decl.c26
-rw-r--r--gcc/fortran/gfortran.h2
-rw-r--r--gcc/fortran/module.c2
-rw-r--r--gcc/fortran/symbol.c4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_proc_16.f0358
7 files changed, 92 insertions, 16 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 31da4d3..a3b3527 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,14 @@
+2010-06-16 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/44549
+ * gfortran.h (gfc_get_typebound_proc): Modified Prototype.
+ * decl.c (match_procedure_in_type): Give a unique gfc_typebound_proc
+ structure to each procedure in a procedure list.
+ * module.c (mio_typebound_proc): Add NULL argument to
+ 'gfc_get_typebound_proc'.
+ * symbol.c (gfc_get_typebound_proc): Add a new argument, which is used
+ to initialize the new structure.
+
2010-06-15 Janus Weil <janus@gcc.gnu.org>
PR fortran/43388
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index f969383..c9b46a2 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -7543,7 +7543,7 @@ match_procedure_in_type (void)
char name[GFC_MAX_SYMBOL_LEN + 1];
char target_buf[GFC_MAX_SYMBOL_LEN + 1];
char* target = NULL, *ifc = NULL;
- gfc_typebound_proc* tb;
+ gfc_typebound_proc tb;
bool seen_colons;
bool seen_attrs;
match m;
@@ -7579,23 +7579,22 @@ match_procedure_in_type (void)
}
/* Construct the data structure. */
- tb = gfc_get_typebound_proc ();
- tb->where = gfc_current_locus;
- tb->is_generic = 0;
+ tb.where = gfc_current_locus;
+ tb.is_generic = 0;
/* Match binding attributes. */
- m = match_binding_attributes (tb, false, false);
+ m = match_binding_attributes (&tb, false, false);
if (m == MATCH_ERROR)
return m;
seen_attrs = (m == MATCH_YES);
/* Check that attribute DEFERRED is given if an interface is specified. */
- if (tb->deferred && !ifc)
+ if (tb.deferred && !ifc)
{
gfc_error ("Interface must be specified for DEFERRED binding at %C");
return MATCH_ERROR;
}
- if (ifc && !tb->deferred)
+ if (ifc && !tb.deferred)
{
gfc_error ("PROCEDURE(interface) at %C should be declared DEFERRED");
return MATCH_ERROR;
@@ -7635,7 +7634,7 @@ match_procedure_in_type (void)
return m;
if (m == MATCH_YES)
{
- if (tb->deferred)
+ if (tb.deferred)
{
gfc_error ("'=> target' is invalid for DEFERRED binding at %C");
return MATCH_ERROR;
@@ -7668,7 +7667,7 @@ match_procedure_in_type (void)
gcc_assert (ns);
/* If the binding is DEFERRED, check that the containing type is ABSTRACT. */
- if (tb->deferred && !block->attr.abstract)
+ if (tb.deferred && !block->attr.abstract)
{
gfc_error ("Type '%s' containing DEFERRED binding at %C "
"is not ABSTRACT", block->name);
@@ -7693,11 +7692,12 @@ match_procedure_in_type (void)
stree = gfc_new_symtree (&ns->tb_sym_root, name);
gcc_assert (stree);
}
- stree->n.tb = tb;
+ stree->n.tb = gfc_get_typebound_proc (&tb);
- if (gfc_get_sym_tree (target, gfc_current_ns, &tb->u.specific, false))
+ if (gfc_get_sym_tree (target, gfc_current_ns, &stree->n.tb->u.specific,
+ false))
return MATCH_ERROR;
- gfc_set_sym_referenced (tb->u.specific->n.sym);
+ gfc_set_sym_referenced (stree->n.tb->u.specific->n.sym);
if (gfc_match_eos () == MATCH_YES)
return MATCH_YES;
@@ -7841,7 +7841,7 @@ gfc_match_generic (void)
}
else
{
- tb = gfc_get_typebound_proc ();
+ tb = gfc_get_typebound_proc (NULL);
tb->where = gfc_current_locus;
tb->access = tbattr.access;
tb->is_generic = 1;
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 8867e58..d77a6c5 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -2545,7 +2545,7 @@ void gfc_free_dt_list (void);
gfc_gsymbol *gfc_get_gsymbol (const char *);
gfc_gsymbol *gfc_find_gsymbol (gfc_gsymbol *, const char *);
-gfc_typebound_proc* gfc_get_typebound_proc (void);
+gfc_typebound_proc* gfc_get_typebound_proc (gfc_typebound_proc*);
gfc_symbol* gfc_get_derived_super_type (gfc_symbol*);
gfc_symbol* gfc_get_ultimate_derived_super_type (gfc_symbol*);
bool gfc_type_is_extension_of (gfc_symbol *, gfc_symbol *);
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 5cd760b..335fd27 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -3324,7 +3324,7 @@ mio_typebound_proc (gfc_typebound_proc** proc)
if (iomode == IO_INPUT)
{
- *proc = gfc_get_typebound_proc ();
+ *proc = gfc_get_typebound_proc (NULL);
(*proc)->where = gfc_current_locus;
}
gcc_assert (*proc);
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 049e4a7..11a0395 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -4591,12 +4591,14 @@ gfc_check_symbol_typed (gfc_symbol* sym, gfc_namespace* ns,
list and marked `error' until symbols are committed. */
gfc_typebound_proc*
-gfc_get_typebound_proc (void)
+gfc_get_typebound_proc (gfc_typebound_proc *tb0)
{
gfc_typebound_proc *result;
tentative_tbp *list_node;
result = XCNEW (gfc_typebound_proc);
+ if (tb0)
+ *result = *tb0;
result->error = 1;
list_node = XCNEW (tentative_tbp);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3c80394..931f91d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-06-16 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/44549
+ * gfortran.dg/typebound_proc_16.f03: New.
+
2010-06-16 Martin Jambor <mjambor@suse.cz>
* g++.dg/torture/pr43905.C: New test.
diff --git a/gcc/testsuite/gfortran.dg/typebound_proc_16.f03 b/gcc/testsuite/gfortran.dg/typebound_proc_16.f03
new file mode 100644
index 0000000..828f510
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/typebound_proc_16.f03
@@ -0,0 +1,58 @@
+! { dg-do compile }
+!
+! PR 44549: [OOP][F2008] Type-bound procedure: bogus error from list after PROCEDURE
+!
+! Contributed by Dominique d'Humieres <dominiq@lps.ens.fr>
+
+MODULE rational_numbers
+ IMPLICIT NONE
+ PRIVATE
+ TYPE,PUBLIC :: rational
+ PRIVATE
+ INTEGER n,d
+
+ CONTAINS
+ ! ordinary type-bound procedure
+ PROCEDURE :: real => rat_to_real
+ ! specific type-bound procedures for generic support
+ PROCEDURE,PRIVATE :: rat_asgn_i, rat_plus_rat, rat_plus_i
+ PROCEDURE,PRIVATE,PASS(b) :: i_plus_rat
+ ! generic type-bound procedures
+ GENERIC :: ASSIGNMENT(=) => rat_asgn_i
+ GENERIC :: OPERATOR(+) => rat_plus_rat, rat_plus_i, i_plus_rat
+ END TYPE
+ CONTAINS
+ ELEMENTAL REAL FUNCTION rat_to_real(this) RESULT(r)
+ CLASS(rational),INTENT(IN) :: this
+ r = REAL(this%n)/this%d
+ END FUNCTION
+
+ ELEMENTAL SUBROUTINE rat_asgn_i(a,b)
+ CLASS(rational),INTENT(OUT) :: a
+ INTEGER,INTENT(IN) :: b
+ a%n = b
+ a%d = 1
+ END SUBROUTINE
+
+ ELEMENTAL TYPE(rational) FUNCTION rat_plus_i(a,b) RESULT(r)
+ CLASS(rational),INTENT(IN) :: a
+ INTEGER,INTENT(IN) :: b
+ r%n = a%n + b*a%d
+ r%d = a%d
+ END FUNCTION
+
+ ELEMENTAL TYPE(rational) FUNCTION i_plus_rat(a,b) RESULT(r)
+ INTEGER,INTENT(IN) :: a
+ CLASS(rational),INTENT(IN) :: b
+ r%n = b%n + a*b%d
+ r%d = b%d
+ END FUNCTION
+
+ ELEMENTAL TYPE(rational) FUNCTION rat_plus_rat(a,b) RESULT(r)
+ CLASS(rational),INTENT(IN) :: a,b
+ r%n = a%n*b%d + b%n*a%d
+ r%d = a%d*b%d
+ END FUNCTION
+END
+
+! { dg-final { cleanup-modules "rational_numbers" } }