Bug 48946 - [OOP] Deferred Overloaded Assignment
Summary: [OOP] Deferred Overloaded Assignment
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid, wrong-code
Depends on:
Blocks:
 
Reported: 2011-05-10 10:06 UTC by Tobias Burnus
Modified: 2012-01-10 09:00 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-05-18 20:06:33


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2011-05-10 10:06:21 UTC
The FE wrongly resolves the operator, leading to "wrong code" in the sense that the linker cannot find the symbol:

undefined reference to `assign_interface_' 


Reported by Andrew Baldwin and reported to work with XLF and NAG.
http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/32602f115b24e19d

Test case:


       module foo_module
        implicit none

        type, abstract :: foo
        contains
          procedure (assign_interface), deferred :: assign
          generic :: assignment(=) => assign
        end type

        abstract interface
          subroutine assign_interface(lhs,rhs)
            import :: foo
            class(foo), intent(inout) :: lhs
            class(foo), intent(in) :: rhs
          end subroutine
        end interface
       end module

       module bar_module
        use foo_module
        implicit none

        type, extends(foo) :: bar
          real :: x
        contains
          procedure :: assign => assign_bar
        end type

       contains
        subroutine assign_bar(lhs,rhs)
          class(bar), intent(inout) :: lhs
          class(foo), intent(in) :: rhs
          select type(rhs)
            type is (bar)
              lhs%x = rhs%x
          end select
        end subroutine
       end module

       program main
        use foo_module
        use bar_module
        implicit none
        type(bar) :: one, two
        one%x = 1
        two%x = 2
        one = two
       end program
Comment 1 janus 2011-05-18 20:06:33 UTC
(In reply to comment #0)
> The FE wrongly resolves the operator, leading to "wrong code" in the sense that
> the linker cannot find the symbol:
> 
> undefined reference to `assign_interface_' 

The dump shows that the assignment "one = two" is incorrectly translated to:

    struct __class_foo_module_Foo class.1;
    struct __class_foo_module_Foo class.0;

    class.0._vptr = (struct __vtype_foo_module_Foo * {ref-all}) &__vtab_bar_module_Bar;
    class.0._data = (struct foo *) &one;
    class.1._vptr = (struct __vtype_foo_module_Foo * {ref-all}) &__vtab_bar_module_Bar;
    class.1._data = (struct foo *) &two;
    assign_interface (&class.0, &class.1);

First we generate two temporaries to convert the TYPE variables to CLASS arguments, which is fine. However, the last line should be a polymorphic call like

class.0._vptr->assign (&class.0, &class.1);


Btw, it works when making the first argument polymorphic:

program main
  use bar_module
  implicit none
  class(bar), allocatable :: one
  type(bar) :: two
  allocate(one)
  one%x = 1
  two%x = 2
  one = two
end program
Comment 2 Tobias Burnus 2012-01-10 09:00:17 UTC
FIXED on the trunk (4.7).

Thanks for the report Andrew!


I think it was done so by the following commit.

Submitted patch: http://gcc.gnu.org/ml/fortran/2012-01/msg00026.html


Author: pault
Date: Thu Jan  5 21:15:52 2012
New Revision: 182929

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182929
Log:
2012-01-05  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/PR48946
	* resolve.c (resolve_typebound_static): If the typebound
	procedure is 'deferred' try to find the correct specific
	procedure in the derived type operator space itself.

2012-01-05  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/PR48946
	* gfortran.dg/typebound_operator_9.f03: This is now a copy of
	the old typebound_operator_8.f03.
	* gfortran.dg/typebound_operator_8.f03: New version of
	typebound_operator_7.f03 with 'u' a derived type instead of a
	class object.

Added:
    trunk/gcc/testsuite/gfortran.dg/typebound_operator_9.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/typebound_operator_8.f03