Bug 52010 - [OOP] Intrinsic assignment of a CLASS to a TYPE
Summary: [OOP] Intrinsic assignment of a CLASS to a TYPE
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Paul Thomas
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2012-01-26 15:45 UTC by Fran Martinez Fadrique
Modified: 2015-10-19 04:40 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.8.5, 4.9.3, 5.2.0, 6.0
Known to fail:
Last reconfirmed: 2012-01-28 00:00:00


Attachments
Test sample (134 bytes, text/x-fortran)
2012-01-26 16:25 UTC, Fran Martinez Fadrique
Details
Test sample to support comment 5 (185 bytes, text/x-fortran)
2012-01-28 23:09 UTC, Fran Martinez Fadrique
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Fran Martinez Fadrique 2012-01-26 15:45:44 UTC
The attached examle generates a compiler error about not being able to convert from CLASS to TYPE being the object of the same declared type.

Reported bug 41719 addresses partially this issue although looking at the standard (7.4.1) I cannot really see that this assignment is incorrect.
The Intel compiler does not complain about this even with the stardard 2003 flags activated.
Comment 1 Dominique d'Humieres 2012-01-26 16:22:51 UTC
> The attached examle generates a compiler error about not being able to convert
> from CLASS to TYPE being the object of the same declared type.

There is no attachment!-(
Comment 2 Fran Martinez Fadrique 2012-01-26 16:25:41 UTC
Created attachment 26473 [details]
Test sample
Comment 3 Tobias Burnus 2012-01-27 16:06:51 UTC
The following handles the checking part. However, one also needs to handle the access internally (in trans-expr.c). Namely:
  type_var = class_var
  type_var = class_function ()
and both for "scalar = scalar", "array = scalar" and "array = array". Note that the class_function can also be an intrinsic function such as RESHAPE. (Cf. PR47505.)

--- expr.c      (revision 183625)
+++ expr.c      (working copy)
@@ -3256,3 +3256,8 @@ gfc_check_assign (gfc_expr *lvalue, gfc_

-  if (gfc_compare_types (&lvalue->ts, &rvalue->ts))
+  if (lvalue->ts.type == BT_DERIVED && rvalue->ts.type == BT_CLASS)
+    {
+      if (gfc_compare_types (&lvalue->ts, &CLASS_DATA (rvalue)->ts))
+       return SUCCESS;
+    }
+  else if (gfc_compare_types (&lvalue->ts, &rvalue->ts))
     return SUCCESS;
Comment 4 Dominique d'Humieres 2012-01-28 17:40:51 UTC
The error is gone with the patch in comment #3. Note that playing with the code, the following two avatars give an ICE after error:

[macbook] f90/bug% diff -up pr52010.f90 pr52010_db_1.f90
--- pr52010.f90	2012-01-26 17:36:45.000000000 +0100
+++ pr52010_db_1.f90	2012-01-26 17:40:47.000000000 +0100
@@ -16,7 +16,7 @@ subroutine subrt( x )
 
  class(t1), intent(in) :: x
  
- type(t1) :: local
+ class(t1) :: local
  
  local = x
 
[macbook] f90/bug% gfc pr52010_db_1.f90
pr52010_db_1.f90:19.19:

 class(t1) :: local
                   1
Error: CLASS variable 'local' at (1) must be dummy, allocatable or pointer
f951: internal compiler error: Segmentation fault

[macbook] f90/bug% diff -up pr52010.f90 pr52010_db_2.f90
--- pr52010.f90	2012-01-26 17:36:45.000000000 +0100
+++ pr52010_db_2.f90	2012-01-26 17:41:50.000000000 +0100
@@ -6,7 +6,7 @@ program test
    integer :: a
  end type
 
- type(t1) :: x
+ class(t1) :: x
 
 call subrt( x )
 
[macbook] f90/bug% gfc pr52010_db_2.f90
pr52010_db_2.f90:9.15:

 class(t1) :: x
               1
Error: CLASS variable 'x' at (1) must be dummy, allocatable or pointer
f951: internal compiler error: Segmentation fault

The backtrace for the first case is

#0  gfc_find_typebound_intrinsic_op (derived=0x0, t=0x7fff5fbfd304, op=INTRINSIC_ASSIGN, noaccess=false, where=0x0)
    at ../../work/gcc/fortran/class.c:946
#1  0x0000000100037746 in matching_typebound_op (tb_base=0x7fff5fbfd368, args=0x141e07910, op=INTRINSIC_ASSIGN, uop=0x0, gname=0x7fff5fbfd360)
    at ../../work/gcc/fortran/interface.c:3199
#2  0x00000001000381db in gfc_extend_assign (c=0x141e16a30, ns=0x0) at ../../work/gcc/fortran/interface.c:3478
#3  0x000000010008c76f in resolve_code (code=<value optimized out>, ns=<value optimized out>) at ../../work/gcc/fortran/resolve.c:9068
#4  0x000000010008f014 in resolve_codes (ns=<value optimized out>) at ../../work/gcc/fortran/resolve.c:13945
#5  0x000000010008ef18 in resolve_codes (ns=<value optimized out>) at ../../work/gcc/fortran/resolve.c:13931
#6  0x000000010007ee38 in gfc_resolve (ns=<value optimized out>) at ../../work/gcc/fortran/resolve.c:13972
#7  0x000000010007477b in gfc_parse_file () at ../../work/gcc/fortran/parse.c:4387
#8  0x00000001000b3486 in gfc_be_parse_file () at ../../work/gcc/fortran/f95-lang.c:250
#9  0x00000001007b8051 in toplev_main (argc=2, argv=0x7fff5fbfd7a0) at ../../work/gcc/toplev.c:557
#10 0x00000001000016c4 in start ()

and for the second case it is

#0  gfc_compare_derived_types (derived1=0x141e13d70, derived2=0x0) at ../../work/gcc/fortran/interface.c:402
#1  0x00000001000a6327 in gfc_type_is_extension_of (t1=0x141e13d70, t2=0x0) at ../../work/gcc/fortran/symbol.c:4823
#2  0x00000001000333cb in gfc_compare_types (ts1=0x141e146c0, ts2=0x141e14328) at ../../work/gcc/fortran/interface.c:495
#3  0x00000001000347aa in compare_parameter (formal=0x141e146a0, actual=0x141e14320, ranks_must_agree=0, is_elemental=<value optimized out>, 
    where=0x141e13878) at ../../work/gcc/fortran/interface.c:1697
#4  0x0000000100035a34 in compare_actual_formal (ap=0x141e138e0, formal=0x141e05f40, ranks_must_agree=0, is_elemental=0, where=0x141e13878)
    at ../../work/gcc/fortran/interface.c:2270
#5  0x0000000100037337 in gfc_procedure_use (sym=0x141e13fc0, ap=0x141e138e0, where=<value optimized out>) at ../../work/gcc/fortran/interface.c:2961
#6  0x0000000100087d59 in resolve_call (c=<value optimized out>) at ../../work/gcc/fortran/resolve.c:3614
#7  0x000000010008c7ce in resolve_code (code=<value optimized out>, ns=<value optimized out>) at ../../work/gcc/fortran/resolve.c:9480
#8  0x000000010008f014 in resolve_codes (ns=<value optimized out>) at ../../work/gcc/fortran/resolve.c:13945
#9  0x000000010007ee38 in gfc_resolve (ns=<value optimized out>) at ../../work/gcc/fortran/resolve.c:13972
#10 0x000000010007477b in gfc_parse_file () at ../../work/gcc/fortran/parse.c:4387
#11 0x00000001000b3486 in gfc_be_parse_file () at ../../work/gcc/fortran/f95-lang.c:250
#12 0x00000001007b8051 in toplev_main (argc=2, argv=0x7fff5fbfd7a0) at ../../work/gcc/toplev.c:557
#13 0x00000001000016c4 in start ()

Should I open new PR(s) for them?
Comment 5 Fran Martinez Fadrique 2012-01-28 23:08:46 UTC
I have bumped into another problem that I think may be related to this same topic.
I have an example that generates the following message:

m_pointer_test.f90:22.2:

  b%pa => a
  1
Error: Different types in pointer assignment at (1); attempted assignment of CLASS(ta) to TYPE(ta)

If in line 14 I make the change from

    type(ta), pointer :: pa => null()

to

    class(ta), pointer :: pa => null()

Then it works but then it does not in my Intel version. Actually I do not see the reason why the change should be made. I have not been able to trace this to the standard.
Comment 6 Fran Martinez Fadrique 2012-01-28 23:09:49 UTC
Created attachment 26494 [details]
Test sample to support comment 5
Comment 7 Paul Thomas 2014-12-29 03:45:49 UTC
My patch for PR63205 fixes the first problem. I'll have a stab at the problem in comment #6 although it has nothing to do with the first.

Paul
Comment 8 Paul Thomas 2014-12-30 03:12:17 UTC
In fact, it appears that both tests are fixed by the current patch in PR63205. This works fine:

module m_test
  implicit none
  type ta
    private
    integer :: i = 99
    contains
      procedure :: suba
  end type ta
  type tb
    private
    class(ta), pointer :: pa => null()
  contains
    procedure :: disp
  end type tb
contains
  function suba( a, v) result(b)
    class(ta), target, intent(inout) :: a
    type(tb) :: b
    integer :: v
    a%i = v
    b%pa => a
  end function suba
  subroutine disp (arg)
    class(tb), intent(in) :: arg
    print *, arg%pa%i
  end subroutine
end module m_test

  use m_test
  class(ta), allocatable :: tgt
  type(tb) :: PTR
  allocate (tgt)
  ptr = tgt%suba(42)
  call ptr%disp
  deallocate (tgt)
end


Paul
Comment 9 Dominique d'Humieres 2015-10-18 20:54:52 UTC
> In fact, it appears that both tests are fixed by the current patch in PR63205.
> This works fine: ...

Confirmed. Closing as FIXED.
Comment 10 paul.richard.thomas@gmail.com 2015-10-19 04:40:54 UTC
Hi Dominique,

I was about to close this one right now.... :-)

Thanks

Paul

On 18 October 2015 at 22:54, dominiq at lps dot ens.fr
<gcc-bugzilla@gcc.gnu.org> wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52010
>
> Dominique d'Humieres <dominiq at lps dot ens.fr> changed:
>
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>              Status|NEW                         |RESOLVED
>       Known to work|                            |4.8.5, 4.9.3, 5.2.0, 6.0
>          Resolution|---                         |FIXED
>
> --- Comment #9 from Dominique d'Humieres <dominiq at lps dot ens.fr> ---
>> In fact, it appears that both tests are fixed by the current patch in PR63205.
>> This works fine: ...
>
> Confirmed. Closing as FIXED.
>
> --
> You are receiving this mail because:
> You are on the CC list for the bug.
> You are the assignee for the bug.