Commit 3e15518b by Janus Weil

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
parent fe27aa8b
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> 2010-06-15 Janus Weil <janus@gcc.gnu.org>
PR fortran/43388 PR fortran/43388
......
...@@ -7543,7 +7543,7 @@ match_procedure_in_type (void) ...@@ -7543,7 +7543,7 @@ match_procedure_in_type (void)
char name[GFC_MAX_SYMBOL_LEN + 1]; char name[GFC_MAX_SYMBOL_LEN + 1];
char target_buf[GFC_MAX_SYMBOL_LEN + 1]; char target_buf[GFC_MAX_SYMBOL_LEN + 1];
char* target = NULL, *ifc = NULL; char* target = NULL, *ifc = NULL;
gfc_typebound_proc* tb; gfc_typebound_proc tb;
bool seen_colons; bool seen_colons;
bool seen_attrs; bool seen_attrs;
match m; match m;
...@@ -7579,23 +7579,22 @@ match_procedure_in_type (void) ...@@ -7579,23 +7579,22 @@ match_procedure_in_type (void)
} }
/* Construct the data structure. */ /* Construct the data structure. */
tb = gfc_get_typebound_proc (); tb.where = gfc_current_locus;
tb->where = gfc_current_locus; tb.is_generic = 0;
tb->is_generic = 0;
/* Match binding attributes. */ /* Match binding attributes. */
m = match_binding_attributes (tb, false, false); m = match_binding_attributes (&tb, false, false);
if (m == MATCH_ERROR) if (m == MATCH_ERROR)
return m; return m;
seen_attrs = (m == MATCH_YES); seen_attrs = (m == MATCH_YES);
/* Check that attribute DEFERRED is given if an interface is specified. */ /* 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"); gfc_error ("Interface must be specified for DEFERRED binding at %C");
return MATCH_ERROR; return MATCH_ERROR;
} }
if (ifc && !tb->deferred) if (ifc && !tb.deferred)
{ {
gfc_error ("PROCEDURE(interface) at %C should be declared DEFERRED"); gfc_error ("PROCEDURE(interface) at %C should be declared DEFERRED");
return MATCH_ERROR; return MATCH_ERROR;
...@@ -7635,7 +7634,7 @@ match_procedure_in_type (void) ...@@ -7635,7 +7634,7 @@ match_procedure_in_type (void)
return m; return m;
if (m == MATCH_YES) if (m == MATCH_YES)
{ {
if (tb->deferred) if (tb.deferred)
{ {
gfc_error ("'=> target' is invalid for DEFERRED binding at %C"); gfc_error ("'=> target' is invalid for DEFERRED binding at %C");
return MATCH_ERROR; return MATCH_ERROR;
...@@ -7668,7 +7667,7 @@ match_procedure_in_type (void) ...@@ -7668,7 +7667,7 @@ match_procedure_in_type (void)
gcc_assert (ns); gcc_assert (ns);
/* If the binding is DEFERRED, check that the containing type is ABSTRACT. */ /* 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 " gfc_error ("Type '%s' containing DEFERRED binding at %C "
"is not ABSTRACT", block->name); "is not ABSTRACT", block->name);
...@@ -7693,11 +7692,12 @@ match_procedure_in_type (void) ...@@ -7693,11 +7692,12 @@ match_procedure_in_type (void)
stree = gfc_new_symtree (&ns->tb_sym_root, name); stree = gfc_new_symtree (&ns->tb_sym_root, name);
gcc_assert (stree); 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; 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) if (gfc_match_eos () == MATCH_YES)
return MATCH_YES; return MATCH_YES;
...@@ -7841,7 +7841,7 @@ gfc_match_generic (void) ...@@ -7841,7 +7841,7 @@ gfc_match_generic (void)
} }
else else
{ {
tb = gfc_get_typebound_proc (); tb = gfc_get_typebound_proc (NULL);
tb->where = gfc_current_locus; tb->where = gfc_current_locus;
tb->access = tbattr.access; tb->access = tbattr.access;
tb->is_generic = 1; tb->is_generic = 1;
......
...@@ -2545,7 +2545,7 @@ void gfc_free_dt_list (void); ...@@ -2545,7 +2545,7 @@ void gfc_free_dt_list (void);
gfc_gsymbol *gfc_get_gsymbol (const char *); gfc_gsymbol *gfc_get_gsymbol (const char *);
gfc_gsymbol *gfc_find_gsymbol (gfc_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_derived_super_type (gfc_symbol*);
gfc_symbol* gfc_get_ultimate_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 *); bool gfc_type_is_extension_of (gfc_symbol *, gfc_symbol *);
......
...@@ -3324,7 +3324,7 @@ mio_typebound_proc (gfc_typebound_proc** proc) ...@@ -3324,7 +3324,7 @@ mio_typebound_proc (gfc_typebound_proc** proc)
if (iomode == IO_INPUT) if (iomode == IO_INPUT)
{ {
*proc = gfc_get_typebound_proc (); *proc = gfc_get_typebound_proc (NULL);
(*proc)->where = gfc_current_locus; (*proc)->where = gfc_current_locus;
} }
gcc_assert (*proc); gcc_assert (*proc);
......
...@@ -4591,12 +4591,14 @@ gfc_check_symbol_typed (gfc_symbol* sym, gfc_namespace* ns, ...@@ -4591,12 +4591,14 @@ gfc_check_symbol_typed (gfc_symbol* sym, gfc_namespace* ns,
list and marked `error' until symbols are committed. */ list and marked `error' until symbols are committed. */
gfc_typebound_proc* gfc_typebound_proc*
gfc_get_typebound_proc (void) gfc_get_typebound_proc (gfc_typebound_proc *tb0)
{ {
gfc_typebound_proc *result; gfc_typebound_proc *result;
tentative_tbp *list_node; tentative_tbp *list_node;
result = XCNEW (gfc_typebound_proc); result = XCNEW (gfc_typebound_proc);
if (tb0)
*result = *tb0;
result->error = 1; result->error = 1;
list_node = XCNEW (tentative_tbp); list_node = XCNEW (tentative_tbp);
......
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> 2010-06-16 Martin Jambor <mjambor@suse.cz>
* g++.dg/torture/pr43905.C: New test. * g++.dg/torture/pr43905.C: New test.
......
! { 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" } }
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