User account creation filtered due to spam.

Bug 47180 - [OOP] EXTENDS_TYPE_OF returns the wrong result for disassociated polymorphic pointers
Summary: [OOP] EXTENDS_TYPE_OF returns the wrong result for disassociated polymorphic ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: 4.6.0
Assignee: janus
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2011-01-05 14:27 UTC by Tobias Burnus
Modified: 2016-11-16 13:47 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-01-05 14:48:38


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2011-01-05 14:27:58 UTC
Found when looking at PR 41580.

The following program should print 6 times "T" but it prints trice "F" followed by trice "T".

From Fortran 2008:
"13.7.60 EXTENDS_TYPE_OF (A, MOLD)"

"Result Value.  [unlimited polymorphic] ; otherwise if the dynamic type of A or MOLD is extensible, the result is true if and only if the dynamic type of A is an extension type of the dynamic type of MOLD; otherwise the result is processor dependent."

"NOTE 13.12  The dynamic type of a disassociated pointer or unallocated allocatable variable is its declared type."


(NAG 5.1 ICEs and ifort prints the same result as gfortran; nevertheless, I expect that the code is correct, which is in line with NOTE 13.12.)


implicit none
type t1
  integer :: a
end type t1
type, extends(t1):: t11
  integer :: b
end type t11

type(t1) a1
type(t11) a11
class(t1), allocatable :: b1
class(t11), allocatable :: b11

print *, extends_type_of(b1,a1)   ! T - currently, gfortran prints "F"
print *, extends_type_of(b11,a1)  ! T - currently, gfortran prints "F"
print *, extends_type_of(b11,a11) ! T - currently, gfortran prints "F"

allocate(t1 :: b1)
allocate(t11 :: b11)

print *, extends_type_of(b1,a1)   ! T
print *, extends_type_of(b11,a1)  ! T
print *, extends_type_of(b11,a11) ! T
end
Comment 1 janus 2011-01-05 14:37:26 UTC
(In reply to comment #0)
> Found when looking at PR 41580.
> 
> The following program should print 6 times "T" but it prints trice "F" followed
> by trice "T".

Actually it does print six time "T" for me!

Are you sure your trunk is up to date?

Note that r168505 is crucial here, which is the fix for PR47024 that I just committed a few hours ago, and which fixes this very issue ...
Comment 2 Tobias Burnus 2011-01-05 14:46:29 UTC
(In reply to comment #1)
> Actually it does print six time "T" for me!
> Are you sure your trunk is up to date?
> Note that r168505 is crucial here, which is the fix for PR47024 that I just
> committed a few hours ago, and which fixes this very issue ...

I think that my vanilla trunk is then not sufficiently up to date; I have another build which contains your patch - but also a draft patch for PR 41580 and is thus not reliably.

Thus, I believe your result: Close as FIXED.
Comment 3 janus 2011-01-05 14:48:38 UTC
(In reply to comment #1)
> Note that r168505 is crucial here, which is the fix for PR47024 that I just
> committed a few hours ago, and which fixes this very issue ...

Anyway r168505 only fixed the issue for allocatables, not pointers! Therefore the following variant indeed still gives the wrong output:


implicit none
type t1
  integer :: a
end type t1
type, extends(t1):: t11
  integer :: b
end type t11

type(t1), target :: a1
type(t11), target :: a11
class(t1), pointer :: b1
class(t11), pointer :: b11

b1 => NULL()
b11 => NULL()

print *, extends_type_of(b1,a1)   ! T - currently, gfortran prints "F"
print *, extends_type_of(b11,a1)  ! T - currently, gfortran prints "F"
print *, extends_type_of(b11,a11) ! T - currently, gfortran prints "F"

b1 => a1
b11 => a11

print *, extends_type_of(b1,a1)   ! T
print *, extends_type_of(b11,a1)  ! T
print *, extends_type_of(b11,a11) ! T
end
Comment 4 janus 2011-01-05 15:08:09 UTC
Draft patch:


Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c	(revision 168504)
+++ gcc/fortran/trans-expr.c	(working copy)
@@ -6121,25 +6121,24 @@ gfc_trans_class_assign (gfc_expr *expr1, gfc_expr
   if (expr2->ts.type != BT_CLASS)
     {
       /* Insert an additional assignment which sets the '_vptr' field.  */
+      gfc_symbol *vtab;
+      gfc_symtree *st;
+
       lhs = gfc_copy_expr (expr1);
       gfc_add_vptr_component (lhs);
+
       if (expr2->ts.type == BT_DERIVED)
-	{
-	  gfc_symbol *vtab;
-	  gfc_symtree *st;
-	  vtab = gfc_find_derived_vtab (expr2->ts.u.derived);
-	  gcc_assert (vtab);
-	  rhs = gfc_get_expr ();
-	  rhs->expr_type = EXPR_VARIABLE;
-	  gfc_find_sym_tree (vtab->name, vtab->ns, 1, &st);
-	  rhs->symtree = st;
-	  rhs->ts = vtab->ts;
-	}
+	vtab = gfc_find_derived_vtab (expr2->ts.u.derived);
       else if (expr2->expr_type == EXPR_NULL)
-	rhs = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
-      else
-	gcc_unreachable ();
+	vtab = gfc_find_derived_vtab (expr1->ts.u.derived);
+      gcc_assert (vtab);
 
+      rhs = gfc_get_expr ();
+      rhs->expr_type = EXPR_VARIABLE;
+      gfc_find_sym_tree (vtab->name, vtab->ns, 1, &st);
+      rhs->symtree = st;
+      rhs->ts = vtab->ts;
+
       tmp = gfc_trans_pointer_assignment (lhs, rhs);
       gfc_add_expr_to_block (&block, tmp);


Will commit as obvious after regtesting.
Comment 5 janus 2011-01-05 18:06:25 UTC
Author: janus
Date: Wed Jan  5 18:06:21 2011
New Revision: 168524

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=168524
Log:
2011-01-05  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/47180
	* trans-expr.c (gfc_trans_class_assign): For a polymorphic NULL pointer
	assignment, set the _vptr component to the declared type.


2011-01-05  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/47180
	* gfortran.dg/extends_type_of_2.f03: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/extends_type_of_2.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
Comment 6 janus 2011-01-05 18:12:48 UTC
Fixed with r168524. Closing.
Comment 7 Dominique d'Humieres 2011-01-05 18:18:34 UTC
Compiling revision 168524 gives:

../../work/gcc/fortran/trans-expr.c: In function 'gfc_trans_class_assign':
../../work/gcc/fortran/trans-expr.c:6172:42: error: 'vtab' may be used uninitialized in this function [-Werror=uninitialized]
cc1: all warnings being treated as errors
Comment 8 Tobias Burnus 2011-01-05 18:34:10 UTC
REOPEN: Causes build issues (cf. comment 7).

      gfc_symbol *vtab;
      if (expr2->ts.type == BT_DERIVED)
        vtab = gfc_find_derived_vtab (expr2->ts.u.derived);
      else if (expr2->expr_type == EXPR_NULL)
        vtab = gfc_find_derived_vtab (expr1->ts.u.derived);
      gcc_assert (vtab);

Which means that "vtab" is not initialized if the "if"/"if else" branch is not entered.

Simple solution:

-     gfc_symbol *vtab;
+     gfc_symbol *vtab = NULL;
Comment 9 Dominique d'Humieres 2011-01-05 18:41:36 UTC
> Simple solution:
>
> -     gfc_symbol *vtab;
> +     gfc_symbol *vtab = NULL;

This is the fix I have also reached and it allows gcc/fortran/trans-expr.c to be compiled.
Comment 10 janus 2011-01-05 18:55:59 UTC
(In reply to comment #8)
> REOPEN: Causes build issues (cf. comment 7).

Thanks for noticing, and sorry for the breakage.


> Simple solution:
> 
> -     gfc_symbol *vtab;
> +     gfc_symbol *vtab = NULL;

Yes, I'll commit shortly.
Comment 11 janus 2011-01-05 19:15:19 UTC
Author: janus
Date: Wed Jan  5 19:14:56 2011
New Revision: 168526

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=168526
Log:
2011-01-05  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/47180
	* trans-expr.c (gfc_trans_class_assign): Bugfix for r168524 (make sure
	'vtab' is initialized).

Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-expr.c
Comment 12 janus 2011-01-05 19:21:18 UTC
Ok. Build problem fixed. Closing, finally.