public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Patch, Fortran, OOP] PR 42207/44064/44065: Undefined reference to  vtab$...
@ 2010-08-04 13:57 Janus Weil
  2010-08-04 14:30 ` Tobias Burnus
  0 siblings, 1 reply; 5+ messages in thread
From: Janus Weil @ 2010-08-04 13:57 UTC (permalink / raw)
  To: gfortran, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1641 bytes --]

Hi all,

the attached patch takes care of the OOP-related linking problems.
AFAICS, it fixes all of PR 42207, 44064 and 44065. The problem was
that in certain situations the vtables were generated too late (i.e.
at translation stage), so that no module variables were generated for
them (this is done in 'gfc_generate_module_vars', which is being
called after resolution). The fix is to call gfc_find_derived_vtab at
resolution stage, to make sure the vtab symbols are present.

The patch also contains a few improvements for gfc_find_derived_vtab:
1) It makes sure that no vtabs are generated for class container
types, but only for the underlying derived type.
2) It cleans up a small error (the reference count for the vtab
symbols was increased for no reason).
3) It follows a suggestion by Mikael to commit the vtab and vtype
symbols one by one (cf. PR 42207 comment #14).

I have included two test cases: The first one is basically comment #4
from PR42207, the second one is comment #3 from PR44065.

Regtested on x86_64-unknown-linux-gnu. Ok for trunk?

Cheers,
Janus



2010-08-04  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/42207
	PR fortran/44064
	PR fortran/44065
	* class.c (gfc_find_derived_vtab): Do not generate vtabs for class
	container types. Do not artificially increase refs. Commit symbols one
	by one.
	* interface.c (compare_parameter): Make sure vtabs are present before
	generating module variables.
	* resolve.c (resolve_allocate_expr): Ditto.


2010-08-04  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/42207
	PR fortran/44064
	PR fortran/44065
	* gfortran.dg/class_25.f03: New.
	* gfortran.dg/class_26.f03: New.

[-- Attachment #2: pr44065.diff --]
[-- Type: application/octet-stream, Size: 2944 bytes --]

Index: gcc/fortran/interface.c
===================================================================
--- gcc/fortran/interface.c	(revision 162864)
+++ gcc/fortran/interface.c	(working copy)
@@ -1423,6 +1423,9 @@ compare_parameter (gfc_symbol *formal, gfc_expr *a
       && actual->ts.u.derived && actual->ts.u.derived->ts.is_iso_c)
     return 1;
 
+  if (formal->ts.type == BT_CLASS)
+    gfc_find_derived_vtab (formal->ts.u.derived);
+
   if (actual->ts.type == BT_PROCEDURE)
     {
       char err[200];
Index: gcc/fortran/class.c
===================================================================
--- gcc/fortran/class.c	(revision 162864)
+++ gcc/fortran/class.c	(working copy)
@@ -322,13 +322,16 @@ gfc_find_derived_vtab (gfc_symbol *derived)
   gfc_namespace *ns;
   gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
   char name[2 * GFC_MAX_SYMBOL_LEN + 8];
-
-  ns = gfc_current_ns;
-
-  for (; ns; ns = ns->parent)
+  
+  /* Find the top-level namespace (MODULE or PROGRAM).  */
+  for (ns = gfc_current_ns; ns; ns = ns->parent)
     if (!ns->parent)
       break;
 
+  /* If the type is a class container, use the underlying derived type.  */
+  if (derived->attr.is_class)
+    derived = gfc_get_derived_super_type (derived);
+    
   if (ns)
     {
       sprintf (name, "vtab$%s", derived->name);
@@ -338,12 +341,13 @@ gfc_find_derived_vtab (gfc_symbol *derived)
 	{
 	  gfc_get_symbol (name, ns, &vtab);
 	  vtab->ts.type = BT_DERIVED;
-	  vtab->attr.flavor = FL_VARIABLE;
+	  if (gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
+	                      &gfc_current_locus) == FAILURE)
+	    goto cleanup;
 	  vtab->attr.target = 1;
 	  vtab->attr.save = SAVE_EXPLICIT;
 	  vtab->attr.vtab = 1;
 	  vtab->attr.access = ACCESS_PUBLIC;
-	  vtab->refs++;
 	  gfc_set_sym_referenced (vtab);
 	  sprintf (name, "vtype$%s", derived->name);
 	  
@@ -358,7 +362,6 @@ gfc_find_derived_vtab (gfc_symbol *derived)
 				  NULL, &gfc_current_locus) == FAILURE)
 		goto cleanup;
 	      vtype->attr.access = ACCESS_PUBLIC;
-	      vtype->refs++;
 	      gfc_set_sym_referenced (vtype);
 
 	      /* Add component '$hash'.  */
@@ -421,7 +424,11 @@ cleanup:
   /* It is unexpected to have some symbols added at resolution or code
      generation time. We commit the changes in order to keep a clean state.  */
   if (found_sym)
-    gfc_commit_symbols ();
+    {
+      gfc_commit_symbol (vtab);
+      if (vtype)
+	gfc_commit_symbol (vtype);
+    }
   else
     gfc_undo_symbols ();
 
Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 162864)
+++ gcc/fortran/resolve.c	(working copy)
@@ -6554,6 +6554,9 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code
 	}
     }
 
+  if (code->ext.alloc.ts.type == BT_DERIVED)
+    gfc_find_derived_vtab (code->ext.alloc.ts.u.derived);
+
   if (pointer || (dimension == 0 && codimension == 0))
     goto success;
 

[-- Attachment #3: class_25.f03 --]
[-- Type: application/octet-stream, Size: 422 bytes --]

! { dg-do run }
!
! PR [OOP] Compile-time errors on typed allocation and pointer function result assignment
!
! Contributed by Damian Rouson <damian@rouson.net>

module m

  implicit none

  type foo 
  end type

  type ,extends(foo) :: bar
  end type

contains

  function new_bar()
    class(foo) ,pointer :: new_bar
    allocate(bar :: new_bar) 
  end function

end module

end 

! { dg-final { cleanup-modules "m" } }

[-- Attachment #4: class_26.f03 --]
[-- Type: application/octet-stream, Size: 539 bytes --]

! { dg-do run }
!
! PR 44065: [OOP] Undefined reference to vtab$...
!
! Contributed by Salvatore Filippone <sfilippone@uniroma2.it>

module s_mat_mod
  implicit none 
  type :: s_sparse_mat
  end type
contains
  subroutine s_set_triangle(a)
    class(s_sparse_mat), intent(inout) :: a
  end subroutine
end module

module s_tester
implicit none
contains
  subroutine s_ussv_2
    use s_mat_mod
    type(s_sparse_mat) :: a
    call s_set_triangle(a)
  end subroutine
end module

end
 
! { dg-final { cleanup-modules "s_mat_mod s_tester" } }

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Patch, Fortran, OOP] PR 42207/44064/44065: Undefined reference to  vtab$...
  2010-08-04 13:57 [Patch, Fortran, OOP] PR 42207/44064/44065: Undefined reference to vtab$ Janus Weil
@ 2010-08-04 14:30 ` Tobias Burnus
  2010-08-04 15:08   ` Janus Weil
  0 siblings, 1 reply; 5+ messages in thread
From: Tobias Burnus @ 2010-08-04 14:30 UTC (permalink / raw)
  To: Janus Weil; +Cc: gfortran, gcc-patches

  On 08/04/2010 03:57 PM, Janus Weil wrote:
> Regtested on x86_64-unknown-linux-gnu. Ok for trunk?

The patch looks OK. However, I was wondering, when reading

+  if (code->ext.alloc.ts.type == BT_DERIVED)
+    gfc_find_derived_vtab (code->ext.alloc.ts.u.derived);


whether one should not restrict this to extensible types (i.e. those 
which are neither SEQUENCE nor Bind(C)). One could add such a check to 
gfc_find_derived_vtab.

And for resolve_allocate_expr shouldn't one check whether either the 
allocatable object or the MOLD is BT_CLASS? I think if neither of them 
is CLASS, one does not need to take care of the vtab, or does one?

Tobias

> 2010-08-04  Janus Weil<janus@gcc.gnu.org>
>
> 	PR fortran/42207
> 	PR fortran/44064
> 	PR fortran/44065
> 	* class.c (gfc_find_derived_vtab): Do not generate vtabs for class
> 	container types. Do not artificially increase refs. Commit symbols one
> 	by one.
> 	* interface.c (compare_parameter): Make sure vtabs are present before
> 	generating module variables.
> 	* resolve.c (resolve_allocate_expr): Ditto.
>
>
> 2010-08-04  Janus Weil<janus@gcc.gnu.org>
>
> 	PR fortran/42207
> 	PR fortran/44064
> 	PR fortran/44065
> 	* gfortran.dg/class_25.f03: New.
> 	* gfortran.dg/class_26.f03: New.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Patch, Fortran, OOP] PR 42207/44064/44065: Undefined reference  to vtab$...
  2010-08-04 14:30 ` Tobias Burnus
@ 2010-08-04 15:08   ` Janus Weil
  2010-08-04 18:44     ` Janus Weil
  0 siblings, 1 reply; 5+ messages in thread
From: Janus Weil @ 2010-08-04 15:08 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: gfortran, gcc-patches

>> Regtested on x86_64-unknown-linux-gnu. Ok for trunk?
>
> The patch looks OK. However, I was wondering, when reading
>
> +  if (code->ext.alloc.ts.type == BT_DERIVED)
> +    gfc_find_derived_vtab (code->ext.alloc.ts.u.derived);
>
>
> whether one should not restrict this to extensible types (i.e. those which
> are neither SEQUENCE nor Bind(C)). One could add such a check to
> gfc_find_derived_vtab.
>
> And for resolve_allocate_expr shouldn't one check whether either the
> allocatable object or the MOLD is BT_CLASS? I think if neither of them is
> CLASS, one does not need to take care of the vtab, or does one?

Right. Checking for BT_CLASS also implies that the type is extensible,
therefore a separate check for extensible types is not necessary. Will
post an updated patch soon.

Cheers,
Janus




>> 2010-08-04  Janus Weil<janus@gcc.gnu.org>
>>
>>        PR fortran/42207
>>        PR fortran/44064
>>        PR fortran/44065
>>        * class.c (gfc_find_derived_vtab): Do not generate vtabs for class
>>        container types. Do not artificially increase refs. Commit symbols
>> one
>>        by one.
>>        * interface.c (compare_parameter): Make sure vtabs are present
>> before
>>        generating module variables.
>>        * resolve.c (resolve_allocate_expr): Ditto.
>>
>>
>> 2010-08-04  Janus Weil<janus@gcc.gnu.org>
>>
>>        PR fortran/42207
>>        PR fortran/44064
>>        PR fortran/44065
>>        * gfortran.dg/class_25.f03: New.
>>        * gfortran.dg/class_26.f03: New.
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Patch, Fortran, OOP] PR 42207/44064/44065: Undefined reference  to vtab$...
  2010-08-04 15:08   ` Janus Weil
@ 2010-08-04 18:44     ` Janus Weil
  2010-08-04 19:52       ` Janus Weil
  0 siblings, 1 reply; 5+ messages in thread
From: Janus Weil @ 2010-08-04 18:44 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: gfortran, gcc-patches

>> The patch looks OK. However, I was wondering, when reading
>>
>> +  if (code->ext.alloc.ts.type == BT_DERIVED)
>> +    gfc_find_derived_vtab (code->ext.alloc.ts.u.derived);
>>
>>
>> whether one should not restrict this to extensible types (i.e. those which
>> are neither SEQUENCE nor Bind(C)). One could add such a check to
>> gfc_find_derived_vtab.
>>
>> And for resolve_allocate_expr shouldn't one check whether either the
>> allocatable object or the MOLD is BT_CLASS? I think if neither of them is
>> CLASS, one does not need to take care of the vtab, or does one?
>
> Right. Checking for BT_CLASS also implies that the type is extensible,
> therefore a separate check for extensible types is not necessary. Will
> post an updated patch soon.

I have now modified the hunk in resolve.c to:

Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 162868)
+++ gcc/fortran/resolve.c	(working copy)
@@ -6554,6 +6554,18 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code
 	}
     }

+  if (e->ts.type == BT_CLASS)
+    {
+      /* Make sure the vtab symbol is present when
+	 the module variables are generated.  */
+      gfc_typespec ts = e->ts;
+      if (code->expr3)
+	ts = code->expr3->ts;
+      else if (code->ext.alloc.ts.type == BT_DERIVED)
+	ts = code->ext.alloc.ts;
+      gfc_find_derived_vtab (ts.u.derived);
+    }
+
   if (pointer || (dimension == 0 && codimension == 0))
     goto success;


Will commit after another regtest.

Cheers,
Janus

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Patch, Fortran, OOP] PR 42207/44064/44065: Undefined reference  to vtab$...
  2010-08-04 18:44     ` Janus Weil
@ 2010-08-04 19:52       ` Janus Weil
  0 siblings, 0 replies; 5+ messages in thread
From: Janus Weil @ 2010-08-04 19:52 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: gfortran, gcc-patches

2010/8/4 Janus Weil <janus@gcc.gnu.org>:
>>> The patch looks OK. However, I was wondering, when reading
>>>
>>> +  if (code->ext.alloc.ts.type == BT_DERIVED)
>>> +    gfc_find_derived_vtab (code->ext.alloc.ts.u.derived);
>>>
>>>
>>> whether one should not restrict this to extensible types (i.e. those which
>>> are neither SEQUENCE nor Bind(C)). One could add such a check to
>>> gfc_find_derived_vtab.
>>>
>>> And for resolve_allocate_expr shouldn't one check whether either the
>>> allocatable object or the MOLD is BT_CLASS? I think if neither of them is
>>> CLASS, one does not need to take care of the vtab, or does one?
>>
>> Right. Checking for BT_CLASS also implies that the type is extensible,
>> therefore a separate check for extensible types is not necessary. Will
>> post an updated patch soon.
>
> I have now modified the hunk in resolve.c to:
>
> Index: gcc/fortran/resolve.c
> ===================================================================
> --- gcc/fortran/resolve.c       (revision 162868)
> +++ gcc/fortran/resolve.c       (working copy)
> @@ -6554,6 +6554,18 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code
>        }
>     }
>
> +  if (e->ts.type == BT_CLASS)
> +    {
> +      /* Make sure the vtab symbol is present when
> +        the module variables are generated.  */
> +      gfc_typespec ts = e->ts;
> +      if (code->expr3)
> +       ts = code->expr3->ts;
> +      else if (code->ext.alloc.ts.type == BT_DERIVED)
> +       ts = code->ext.alloc.ts;
> +      gfc_find_derived_vtab (ts.u.derived);
> +    }
> +
>   if (pointer || (dimension == 0 && codimension == 0))
>     goto success;
>
>
> Will commit after another regtest.


Committed as r162879:

http://gcc.gnu.org/viewcvs?view=revision&revision=162879

Cheers,
Janus

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-08-04 19:52 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-04 13:57 [Patch, Fortran, OOP] PR 42207/44064/44065: Undefined reference to vtab$ Janus Weil
2010-08-04 14:30 ` Tobias Burnus
2010-08-04 15:08   ` Janus Weil
2010-08-04 18:44     ` Janus Weil
2010-08-04 19:52       ` Janus Weil

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).