Bug 51754 - [OOP] ICE on valid with class arrays
[OOP] ICE on valid with class arrays
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.7.0
: P3 normal
: ---
Assigned To: Not yet assigned to anyone
:
Depends on: 46356
Blocks:
  Show dependency treegraph
 
Reported: 2012-01-04 17:28 UTC by Andrew Benson
Modified: 2012-02-06 04:14 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-01-28 00:00:00


Attachments
This fixes the ice-on-valid of comment #0 (3.68 KB, patch)
2012-01-29 14:51 UTC, Mikael Morin
Details | Diff
This fixes the class_41 failure with the previous patch (2.74 KB, patch)
2012-01-29 14:53 UTC, Mikael Morin
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Benson 2012-01-04 17:28:24 UTC
This test case gives an ICE on valid related to class arrays:

module test
  private

  type :: componentB
  end type componentB
  
  type :: treeNode
     class(componentB), allocatable, dimension(:) :: componentB
  end type treeNode
  
contains
  
  function BGet(self)
    implicit none
    class(componentB), pointer :: BGet
    class(treeNode), intent(in) :: self
    select type (self)
    class is (treeNode)
       BGet => self%componentB(1)
    end select
    return
  end function BGet
  
end module test

$ gfortran -v
Using built-in specs.
COLLECT_GCC=/opt/gcc-4.7/bin/gfortran
COLLECT_LTO_WRAPPER=/opt/gcc-4.7/libexec/gcc/x86_64-unknown-linux-
gnu/4.7.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.7/configure --prefix=/opt/gcc-4.7 --enable-
languages=c,c++,fortran --disable-multilib
Thread model: posix
gcc version 4.7.0 20120103 (experimental) (GCC)
$ gfortran -c test.F90 -o test.o
test.F90: In function ‘bget’:
test.F90:19:0: internal compiler error: in gfc_conv_descriptor_offset, at 
fortran/trans-array.c:210
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

If I remove the "allocatable" I instead get:

$ gfortran -c test.F90 -o test.o
f951: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.


If I remove the "dimension(:)" and change the pointer association to:

       BGet => self%componentB

then it compiles successfully.
Comment 1 Tobias Burnus 2012-01-21 18:28:46 UTC
TODO: The ICE for the valid code (gfc_conv_descriptor_offset).

This comment is for the second issue:

(In reply to comment #0)
> If I remove the "allocatable" I instead get:
> $ gfortran -c test.F90 -o test.o
> f951: internal compiler error: Segmentation fault

Draft patch - for some reason, two error messages are printed for the line
  class(componentB), dimension(:) :: componentB

The change in gfc_default_initializer fixes the initial issue (and causes the duplicated error message be printed in resolve.c) [Before, resolve was not reached as the function was already called during variable declaration.] -- The other parts are to avoid later segfault ("error recovery").

--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -3761,3 +3761,9 @@ gfc_default_initializer (gfc_typespec *ts)
-    if (comp->initializer || comp->attr.allocatable
-       || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)->attr.allocatable))
-      break;
+    {
+      if (comp->ts.type == BT_CLASS && !comp->attr.class_ok)
+       return NULL;
+
+      if (comp->initializer || comp->attr.allocatable
+         || (comp->ts.type == BT_CLASS
+             &&  CLASS_DATA (comp)->attr.allocatable))
+       break;
+    }
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -2020 +2020 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
-      else if (component->ts.type == BT_CLASS
+      else if (component->ts.type == BT_CLASS && component->attr.class_ok
@@ -2188 +2188 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts)
-       if (comp->ts.type == BT_CLASS)
+       if (comp->ts.type == BT_CLASS && comp->attr.class_ok)
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -4836,2 +4836,2 @@ gfc_type_compatible (gfc_typespec *ts1, gfc_typespec *ts2)
-  bool is_class1 = (ts1->type == BT_CLASS);
-  bool is_class2 = (ts2->type == BT_CLASS);
+  bool is_class1 = (ts1->type == BT_CLASS && ts1->u.derived->attr.class_ok);
+  bool is_class2 = (ts2->type == BT_CLASS && ts2->u.derived->attr.class_ok);
Comment 2 Tobias Burnus 2012-01-21 19:22:27 UTC
(In reply to comment #1)
One additionally needs the following - otherwise, e.g., PR 41600 comment 1 fails at resolve time claiming that the type is not the same.

--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -385,2 +385,3 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
       fclass->attr.abstract = ts->u.derived->attr.abstract;
+      fclass->attr.class_ok = 1;
       if (ts->u.derived->f2k_derived)
Comment 3 Dominique d'Humieres 2012-01-27 22:15:48 UTC
Trunk r183622 now gives

pr51754.f90:19.15:

       BGet => self%componentB(1)
               1
Error: Pointer assignment target is neither TARGET nor POINTER at (1)

(r183618 gives the ICE). The change is likely due to the fix for pr51970/51977: i.e., r183622.
Comment 4 Tobias Burnus 2012-01-28 09:21:07 UTC
(In reply to comment #3)
> Trunk r183622 now gives
>        BGet => self%componentB(1)
> Error: Pointer assignment target is neither TARGET nor POINTER at (1)

The message is valid: one has to add the TARGET attribute to "self" or make "componentB" a POINTER. Doing so, one gets again the ICE in gfc_conv_descriptor_offset.
Comment 5 Dominique d'Humieres 2012-01-28 11:32:40 UTC
> The message is valid: one has to add the TARGET attribute to "self" or make
> "componentB" a POINTER. Doing so, one gets again the ICE in
> gfc_conv_descriptor_offset.

Confirmed. Are the patches in comment #1 and #2 still supposed to fix it?
Comment 6 Dominique d'Humieres 2012-01-28 11:33:25 UTC
Marking the pr as confirmed.
Comment 7 Tobias Burnus 2012-01-28 12:03:22 UTC
(In reply to comment #5)
> Are the patches in comment #1 and #2 still supposed to fix it?

Those patches fix the ICE-on-invalid-code issue (segfault), i.e. the test case in comment 0 without "allocatable".

It does not fix the ICE-on-valid-code issue of comment 0 (ICE in gfc_conv_descriptor_offset), i.e. the test case of comment 0 with TARGET added.
Comment 8 Mikael Morin 2012-01-29 14:51:48 UTC
Created attachment 26504 [details]
This fixes the ice-on-valid of comment #0

This patch (extracted from PR50981 comment #28) fixes the ICEs of:
PR51754 comment #0
PR46356 comment #2
PR41587 comment #1

It regresses in class_41.f03 because of the interface mapping mechanism for character length.  There is a type mismatch between the dummy argument (of a base type) and the corresponding actual argument (of an extended type).  The shadow symbol created for interface mapping has the base type, but its backend decl has the extended type.  It works without the patch because the missing "_data" reference is implicitly added by conv_parent_component_references (and it is the "_data" component of the extended type).  It fails with the patch because the "_data" component is added explicitly, but as we are working with the frontend structures we add the "_data" component of the base type.  When translating with the extended type declaration we don't find the right component and fail because of the type mismatch.
Comment 9 Mikael Morin 2012-01-29 14:53:50 UTC
Created attachment 26505 [details]
This fixes the class_41 failure with the previous patch

This fixes the failure describe above but regresses on module_read_2.f90.
I'm giving up.
Comment 10 Tobias Burnus 2012-01-29 18:49:10 UTC
When fixed, correctness check should be added to test3() of the test case submitted at http://gcc.gnu.org/ml/fortran/2012-01/msg00252.html
Comment 11 Mikael Morin 2012-02-02 23:11:01 UTC
Author: mikael
Date: Thu Feb  2 23:10:55 2012
New Revision: 183853

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=183853
Log:
2012-02-02  Mikael Morin  <mikael@gcc.gnu.org>

	PR fortran/41587
	PR fortran/46356
	PR fortran/51754
	PR fortran/50981
	* class.c (insert_component_ref, class_data_ref_missing,
	gfc_fix_class_refs): New functions.
	* gfortran.h (gfc_fix_class_refs): New prototype.
	* trans-expr.c (gfc_conv_expr): Remove special case handling and call
	gfc_fix_class_refs instead.

2012-02-02  Mikael Morin  <mikael@gcc.gnu.org>

	PR fortran/41587
	* gfortran.dg/class_array_10.f03: New test.

	PR fortran/46356
	* gfortran.dg/class_array_11.f03: New test.

	PR fortran/51754
	* gfortran.dg/class_array_12.f03: New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/class_array_10.f03
    trunk/gcc/testsuite/gfortran.dg/class_array_11.f03
    trunk/gcc/testsuite/gfortran.dg/class_array_12.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/class.c
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
Comment 12 Tobias Burnus 2012-02-05 10:36:40 UTC
I think this PR is now fixed (on the 4.7 trunk).

Thanks for the bug report Andrew! And thanks Mikael for the patch!


(In reply to comment #10)
> When fixed, correctness check should be added to test3() of the test case
> submitted at http://gcc.gnu.org/ml/fortran/2012-01/msg00252.html

I did so; cf. PR fortran/51972 comment 6 and
http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=183904
Comment 13 Andrew Benson 2012-02-06 04:14:15 UTC
I'll look forward to trying using class arrays again in my code.