Bug 42207

Summary: [OOP] Compile-time errors on typed allocation and pointer function result assignment
Product: gcc Reporter: Damian Rouson <damian>
Component: fortranAssignee: janus
Status: RESOLVED FIXED    
Severity: normal CC: gcc-bugs, janus, klaas_giesbertz, paul.richard.thomas
Priority: P3 Keywords: rejects-valid
Version: 4.5.0   
Target Milestone: 4.6.0   
Host: Mac OS X 10.5.8 Target: Mac OS X 10.5.8
Build: Mac OS X 10.5.8 Known to work:
Known to fail: Last reconfirmed: 2010-08-03 16:31:55

Description Damian Rouson 2009-11-28 18:14:31 UTC
After a fresh fortran-dev checkout, configure, make, and make install, the first two modules below compile correctly, while the third produces the the compile-time errors shown.  The two offending lines are the "allocate" statement and the subsequent pointer assignment, both in the "new_bar" function.  Based on the error message, this is related to vtabs.  Apparently the error is platform-dependent since Janus reports compiling similar code with no problem.

Damian

$ cat foo.f03 
module foo_module
  implicit none
  type foo 
  end type
end module

$ cat bar.f03 
module bar_module
  use foo_module
  implicit none
  type ,extends(foo) :: bar
  end type
contains
  function bar_()
    type(bar) ,pointer :: bar_ 
    bar_ => null()
  end function
end module

$ cat bar_factory.f03 
module bar_factory_module
  implicit none
  type bar_factory
  contains 
    procedure :: new_bar
  end type 
contains
  function new_bar(this) 
    use bar_module
    use foo_module 
    class(bar_factory), intent(in) :: this
    class(foo) ,pointer :: new_bar
    allocate(bar :: new_bar)
    new_bar => bar_() 
  end function
end module

$ gfortran -c foo.f03
$ gfortran -c bar.f03
$ gfortran -c bar_factory.f03 
/var/folders/aN/aNwnamXwF00CoxUk5fEVmU+++TM/-Tmp-//cciAcMyX.s:37:non-relocatable subtraction expression, "_vtab$bar.1525" minus "L00000000001$pb"
/var/folders/aN/aNwnamXwF00CoxUk5fEVmU+++TM/-Tmp-//cciAcMyX.s:37:symbol: "_vtab$bar.1525" can't be undefined in a subtraction expression
/var/folders/aN/aNwnamXwF00CoxUk5fEVmU+++TM/-Tmp-//cciAcMyX.s:35:non-relocatable subtraction expression, "_vtab$bar.1525" minus "L00000000001$pb"
/var/folders/aN/aNwnamXwF00CoxUk5fEVmU+++TM/-Tmp-//cciAcMyX.s:35:symbol: "_vtab$bar.1525" can't be undefined in a subtraction expression
Comment 1 Salvatore Filippone 2009-11-28 18:25:05 UTC
(In reply to comment #0)
> After a fresh fortran-dev checkout, configure, make, and make install, the
> first two modules below compile correctly, while the third produces the the
>
Well, for me it works under linux (fedora 11) on both i686 (32 bits) and x86_64, on a fresh checkout of fortran-dev.

Comment 2 Dominique d'Humieres 2009-11-28 20:18:45 UTC
On darwin, the errors appear only in 32 bit mode. I am sure that I have already seen such errors in the past, but I cannot remember where or when!-(
Comment 3 Damian Rouson 2009-11-29 02:50:11 UTC
(In reply to comment #2)
> On darwin, the errors appear only in 32 bit mode. I am sure that I have already
> seen such errors in the past, but I cannot remember where or when!-(
> 

Thanks for all of your help.  So how do I switch to 64-bit mode?

Damian

Comment 4 janus 2009-11-29 12:31:41 UTC
(In reply to comment #2)
> On darwin, the errors appear only in 32 bit mode.

Yes, I can confirm this on x86_64-apple-darwin10.2.0. Also, I just ran the fortran testsuite for the fortran-dev branch on darwin, but saw no failures.

Here is a reduced test case:


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


Important: This only happens inside a module. If I remove the "module m/end module" in the example, the error goes away.
Comment 5 Dominique d'Humieres 2009-11-29 16:21:53 UTC
(In reply to comment #3)
> So how do I switch to 64-bit mode?

On x86_64-apple-darwin* it is the default, so I assume you are using i686-apple-darwin*. In this case you need a "multlib" build and you compile with -m64.
Comment 6 Damian Rouson 2009-11-30 00:51:44 UTC
(In reply to comment #5)
> (In reply to comment #3)
> > So how do I switch to 64-bit mode?
> 
> On x86_64-apple-darwin* it is the default, so I assume you are using
> i686-apple-darwin*. In this case you need a "multlib" build and you compile
> with -m64.
> 

Switching to x86_64-apple-darwin9  worked!  What does the "9" mean?  Since I'm running OS X 10.5.8, I first tried "10.5.8" and "10", but neither worked. 

Damian
Comment 7 Damian Rouson 2009-11-30 01:16:27 UTC
Janus,

Although the new reduced case compiles fine in 64-bit mode, I run into linking problems as soon as I add "program main;  end program" to the end of it:

Undefined symbols:
  "_vtab$bar.1550", referenced from:
      ___m_MOD_new_bar in ccQEi2ET.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

Looking back through my e-mails, I see that you told me on 11/21 that Paul's TBP patch had not yet been applied to the branch or the trunk. From the above results, I assume that's still the case.

Damian


(In reply to comment #4)
> (In reply to comment #2)
> > On darwin, the errors appear only in 32 bit mode.
> 
> Yes, I can confirm this on x86_64-apple-darwin10.2.0. Also, I just ran the
> fortran testsuite for the fortran-dev branch on darwin, but saw no failures.
> 
> Here is a reduced test case:
> 
> 
> 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
> 
> 
> Important: This only happens inside a module. If I remove the "module m/end
> module" in the example, the error goes away.
> 

Comment 8 Tobias Burnus 2010-08-03 10:03:33 UTC
If I run the code in comment 4 with an appended "end" (to make it a complete program), I (still) get link errors:

/tmp/cc3J3Ygi.o: In function `__m_MOD_new_bar':
aa3.f90:(.text+0x2c): undefined reference to `vtab$bar.1527'

That's with trunk 4.6.0 20100803 (Rev. 162828) x86_64-unknown-linux-gnu with both -m32 and -m64 - thus I do not think that this is target dependent.


The problem is also obvious: No vtable is created - as mentioned the other day, I think generating the vtable only when using the a polymorphic type - but then initializing it several times - seems to be the wrong approach.
Comment 9 janus 2010-08-03 11:36:07 UTC
(In reply to comment #8)
> If I run the code in comment 4 with an appended "end" (to make it a complete
> program), I (still) get link errors:
> 
> /tmp/cc3J3Ygi.o: In function `__m_MOD_new_bar':
> aa3.f90:(.text+0x2c): undefined reference to `vtab$bar.1527'
> 
> That's with trunk 4.6.0 20100803 (Rev. 162828) x86_64-unknown-linux-gnu with
> both -m32 and -m64 - thus I do not think that this is target dependent.

Well, what is target dependent are the funny messages in comment #0, which are only seen on darwin with -m32.

For the 'undefined reference' errors we have other PRs in fact (e.g. PR44065).
Comment 10 Dominique d'Humieres 2010-08-03 11:49:20 UTC
> Well, what is target dependent are the funny messages in comment #0, which are
> only seen on darwin with -m32.

I think it is a bogus way to "report" the 'undefined reference'.
Comment 11 Tobias Burnus 2010-08-03 11:51:42 UTC
(In reply to comment #9)
> Well, what is target dependent are the funny messages in comment #0, which are
> only seen on darwin with -m32.

I have to admit that the -fdump-tree-original-all looks strange to me (third file of comment 0):

(struct vtype$foo *) __result_new_barD.1574.$vptrD.1556 = (struct vtype$foo *) &vtab$barD.1584;
(struct vtype$foo *) __result_new_barD.1574.$vptrD.1556 = (struct vtype$foo *) &vtab$barD.1584;

Why is there a cast on the LHS? (The code might be valid though - am not really a tree expert.)
Comment 12 janus 2010-08-03 12:59:15 UTC
(In reply to comment #8)
> If I run the code in comment 4 with an appended "end" (to make it a complete
> program), I (still) get link errors:
> 
> /tmp/cc3J3Ygi.o: In function `__m_MOD_new_bar':
> aa3.f90:(.text+0x2c): undefined reference to `vtab$bar.1527'


This error can be fixed by:


Index: match.c
===================================================================
--- match.c     (revision 162839)
+++ match.c     (working copy)
@@ -2902,6 +2902,9 @@ gfc_match_allocate (void)
                         &tail->expr->where);
              goto cleanup;
            }
+
+         if (ts.type == BT_DERIVED)
+           gfc_find_derived_vtab (ts.u.derived);
        }
 
       if (tail->expr->ts.type == BT_DERIVED)


Disclaimer: I haven't checked this for regressions. And I'm not sure yet if it really is the proper fix for this issue.
Comment 13 Dominique d'Humieres 2010-08-03 13:43:09 UTC
(In reply to comment #12)
> Disclaimer: I haven't checked this for regressions. And I'm not sure yet if it
> really is the proper fix for this issue.

The patch fixes the tests in this pr, but not those in pr44065. So far I have regtested the *.f03 files without regression. Further testing in progress. Thanks.

Comment 14 Mikael Morin 2010-08-03 14:31:23 UTC
(In reply to comment #12)
> 
> This error can be fixed by:
> [...]

You may need to change the recently added gfc_commit_symbols in gfc_find_derived_vtabs into a per symbol gfc_commit_symbol (symbol). 
Otherwise one can error out, but yet commit the symbols. Who knows what can happen then ? ;-) 
Comment 15 Dominique d'Humieres 2010-08-03 15:31:30 UTC
I don't know if this related to comment #14, but with the patch of comment #12 the errors for the test pr37425#0 has changed from

pr37425.f90:7.13:

    PROCEDURE :: assign_t_from_int
             1
Error: Non-polymorphic passed-object dummy argument of 'assign_t_from_int' at (1)
pr37425.f90:8.13:

    PROCEDURE :: equals_t_int
             1
Error: Non-polymorphic passed-object dummy argument of 'equals_t_int' at (1)
pr37425.f90:22.31:

  LOGICAL FUNCTION equals_t_int (me, i)
                               1
Error: First argument of operator interface at (1) must be INTENT(IN)

to

pr37425.f90:7.13:

    PROCEDURE :: assign_t_from_int
             1
Error: Non-polymorphic passed-object dummy argument of 'assign_t_from_int' at (1)
pr37425.f90:8.13:

    PROCEDURE :: equals_t_int
             1
Error: Non-polymorphic passed-object dummy argument of 'equals_t_int' at (1)
pr37425.f90:10.30:

    GENERIC :: OPERATOR(==) => equals_t_int
                              1
Error: Undefined specific binding 'equals_t_int' as target of GENERIC '==' at (1)
pr37425.f90:9.31:

    GENERIC :: ASSIGNMENT(=) => assign_t_from_int
                               1
Error: Undefined specific binding 'assign_t_from_int' as target of GENERIC '=' at (1)
Comment 16 janus 2010-08-03 16:31:55 UTC
(In reply to comment #15)
> I don't know if this related to comment #14, but with the patch of comment #12
> the errors for the test pr37425#0 has changed from

The patch in comment #12 is actually not the best thing to do. Here is a better patch:


Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c       (revision 162840)
+++ gcc/fortran/resolve.c       (working copy)
@@ -6508,6 +6508,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;
 
Comment 17 Dominique d'Humieres 2010-08-03 18:08:39 UTC
With the patch in comment #16 (and the patches for pr44065 and pr44857) gfortran.dg/typebound_operator_4.f03 fails:

FAIL: gfortran.dg/typebound_operator_4.f03  -O  (test for excess errors)

the extra errors are:

/opt/gcc/work/gcc/testsuite/gfortran.dg/typebound_operator_4.f03:73.7:

  USE m
       1
Error: Invalid expression in the derived type constructor for pointer component '$extends' at (1) in PURE procedure
/opt/gcc/work/gcc/testsuite/gfortran.dg/typebound_operator_4.f03:73.7:

  USE m
       1
Error: Invalid expression in the derived type constructor for pointer component '$extends' at (1) in PURE procedure

at the beginning and 

/opt/gcc/work/gcc/testsuite/gfortran.dg/typebound_operator_4.f03:89.14:

  x = x .PLUS. 5 ! { dg-error "Unknown operator" }
              1
Error: Unknown operator 'plus' at (1)

at the end. I also see the change reported in comment #15.
Comment 18 Dominique d'Humieres 2010-08-03 18:55:03 UTC
Two mistakes in comment #17:

(1) The extra errors are due to the patch in comment #5 of pr44065.

(2) There are only two extra errors at the beginning.
Comment 19 janus 2010-08-04 07:31:05 UTC
(In reply to comment #16)
> Here is a better patch:

This patch also fixes the error messages in comment #0 on darwin with -m32.
Comment 20 janus 2010-08-04 19:49:39 UTC
Subject: Bug 42207

Author: janus
Date: Wed Aug  4 19:49:19 2010
New Revision: 162879

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=162879
Log:
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.

Added:
    trunk/gcc/testsuite/gfortran.dg/class_25.f03
    trunk/gcc/testsuite/gfortran.dg/class_26.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/class.c
    trunk/gcc/fortran/interface.c
    trunk/gcc/fortran/resolve.c
    trunk/gcc/testsuite/ChangeLog

Comment 21 janus 2010-08-04 20:00:55 UTC
Fixed with r162879. Closing.