Bug 52968 - [OOP] Call to type-bound procedure wrongly rejected
[OOP] Call to type-bound procedure wrongly rejected
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.8.0
: P3 normal
: ---
Assigned To: janus
: rejects-valid
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-04-13 00:36 UTC by reubendb
Modified: 2012-04-16 08:53 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-04-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description reubendb 2012-04-13 00:36:26 UTC
The following code illustrate the problem. Compiled with gcc 4.8.0 20120408, I got this error message:

$> gfortran -c solvermod.f90 
solvermod.f90:21.31:

   call S % Equation % Evaluate ()
                               1
Error: 'evaluate' at (1) is not a member of the 'equationtemplate' structure

The error dissapear when EquationTemplate is defined before SolverType in the code below. 

----------------------
module SolverModule

 type :: SolverType
   class ( EquationTemplate ), pointer :: Equation
 end type

 type :: EquationTemplate
 contains
   procedure :: Evaluate
 end type

contains

  subroutine Evaluate ( ET )
    class ( EquationTemplate ) :: ET
  end subroutine

 subroutine Solve
   type ( SolverType ) :: S
   call S % Equation % Evaluate ()
 end subroutine

end module
--------------------
Comment 1 Tobias Burnus 2012-04-13 07:14:46 UTC
What happens is the following (cf. primary.c's gfc_match_varspec):

In the first step, "S % Equation" is matched. One then has:
  component = gfc_find_component (sym, name, false, false);
  ...
  sym = component->ts.u.derived;
where sym "__class_solvermodule_Equationtemplate_p".

Next, one tries to match "% Evaluate" as type-bound procedure:

  if (sym->f2k_derived)
    tbp = gfc_find_typebound_proc (sym, &t, name, false, &gfc_current_locus);

However, the class container does not have f2k_derived - only the "_data" component has.


Unsurprisingly, it works if one replaces in "type :: SolverType" the CLASS pointer by a TYPE pointer. I have no idea why changing the order of the two type declarations helps - but I didn't try hard.
Comment 2 janus 2012-04-13 13:32:00 UTC
(In reply to comment #1)
> Next, one tries to match "% Evaluate" as type-bound procedure:
> 
>   if (sym->f2k_derived)
>     tbp = gfc_find_typebound_proc (sym, &t, name, false, &gfc_current_locus);
> 
> However, the class container does not have f2k_derived - only the "_data"
> component has.

Right. The class container's f2k_derived should be set up in 'gfc_build_class_symbol'. However, this is called before the type 'EquationTemplate' is available, and setting up the f2k_derived fails for this reason.

Patch:

Index: gcc/fortran/class.c
===================================================================
--- gcc/fortran/class.c	(revision 186413)
+++ gcc/fortran/class.c	(working copy)
@@ -541,8 +541,7 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_a
       fclass->refs++;
       fclass->ts.type = BT_UNKNOWN;
       fclass->attr.abstract = ts->u.derived->attr.abstract;
-      if (ts->u.derived->f2k_derived)
-	fclass->f2k_derived = gfc_get_namespace (NULL, 0);
+      fclass->f2k_derived = gfc_get_namespace (NULL, 0);
       if (gfc_add_flavor (&fclass->attr, FL_DERIVED,
 	  NULL, &gfc_current_locus) == FAILURE)
 	return FAILURE;


This makes the test case compile correctly (and is free of testsuite regressions).
Comment 3 janus 2012-04-13 14:02:05 UTC
This bug is similar to PR51995, and in fact the patch from comment #2 above seems to supersede the solution given there (which could be removed as a consequence):

Index: gcc/fortran/class.c
===================================================================
--- gcc/fortran/class.c	(revision 186413)
+++ gcc/fortran/class.c	(working copy)
@@ -541,8 +541,7 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_a
       fclass->refs++;
       fclass->ts.type = BT_UNKNOWN;
       fclass->attr.abstract = ts->u.derived->attr.abstract;
-      if (ts->u.derived->f2k_derived)
-	fclass->f2k_derived = gfc_get_namespace (NULL, 0);
+      fclass->f2k_derived = gfc_get_namespace (NULL, 0);
       if (gfc_add_flavor (&fclass->attr, FL_DERIVED,
 	  NULL, &gfc_current_locus) == FAILURE)
 	return FAILURE;
@@ -579,8 +578,6 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_a
       c->attr.access = ACCESS_PRIVATE;
       c->attr.pointer = 1;
     }
-  else if (!fclass->f2k_derived)
-    fclass->f2k_derived = gfc_get_namespace (NULL, 0);
 
   /* Since the extension field is 8 bit wide, we can only have
      up to 255 extension levels.  */
Comment 4 janus 2012-04-16 08:48:18 UTC
Author: janus
Date: Mon Apr 16 08:48:11 2012
New Revision: 186486

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=186486
Log:
2012-04-16  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/52968
	* class.c (gfc_build_class_symbol): Make sure the 'f2k_derived'
	namespace is present.


2012-04-16  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/52968
	* gfortran.dg/typebound_call_23.f03: New test case.

Added:
    trunk/gcc/testsuite/gfortran.dg/typebound_call_23.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/class.c
    trunk/gcc/testsuite/ChangeLog
Comment 5 janus 2012-04-16 08:53:10 UTC
Fixed with r186486. Closing.

Thanks for reporting!