Bug 54881

Summary: [4.8 Regression] [OOP] ICE in fold_convert_loc, at fold-const.c:2016
Product: gcc Reporter: Richard L Lozes <richard>
Component: fortranAssignee: janus
Status: RESOLVED FIXED    
Severity: normal CC: jakub, janus
Priority: P4 Keywords: ice-on-valid-code
Version: 4.7.2   
Target Milestone: 4.8.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2012-10-10 00:00:00
Attachments: Source code reproducing bug

Description Richard L Lozes 2012-10-09 21:19:14 UTC
Created attachment 28406 [details]
Source code reproducing bug

~/Tests> gfortran -Wall -fbounds-check -Wtabs -g -c ../Source/CompilerBug.f03
../Source/CompilerBug.f03:124.22:

    integer*4 :: istat
                      1
Warning: Unused variable 'istat' declared at (1)
../Source/CompilerBug.f03: In function 'destroydnode':
../Source/CompilerBug.f03:129:0: internal compiler error: in fold_convert_loc, at fold-const.c:2016
Please submit a full bug report, ...


~/Tests> gfortran --version
GNU Fortran (SUSE Linux) 4.7.2 20120920 [gcc-4_7-branch revision 191568]
Copyright (C) 2012 Free Software Foundation, Inc.

~/Tests> gfortran -dumpmachine
i586-suse-linux
Comment 1 Dominique d'Humieres 2012-10-10 07:38:39 UTC
I get the ICE with 4.7.2, but the trunk gives

pr54881.f90:140.24:

      call DestroyNode (theNode, lstatus )
                        1
Error: Actual argument for 'thenode' must be a pointer at (1)

which seems weird (AFAICT theNode is a pointer).
Comment 2 janus 2012-10-10 08:11:59 UTC
While trying to reduce it, I found a version which also ICEs with trunk:

  implicit none

  type treeNode
    type(treeNode), pointer    :: right    => null()
  end type

  type(treeNode), pointer :: theNode
  print *, associated( RightOf(theNode) )
  
contains

  function RightOf( theNode )
    class(treeNode), pointer :: RightOf
    type(treeNode), target, intent(in)    :: theNode
    RightOf => theNode%right
  end function
  
end


Apparently, the ICE on the original test case was only prevented by the error message mentioned by Dominique.


With 4.8 trunk one gets the following output:

CompilerBug.f03:10:0: internal compiler error: in fold_convert_loc, at fold-const.c:1979
   print *, associated( RightOf(theNode) )
 ^
0x8070d4 fold_convert_loc(unsigned int, tree_node*, tree_node*)
        /home/jweil/gcc48/trunk/gcc/fold-const.c:1979
0x654b90 gfc_conv_associated
        /home/jweil/gcc48/trunk/gcc/fortran/trans-intrinsic.c:5768
0x656501 gfc_conv_intrinsic_function(gfc_se*, gfc_expr*)
        /home/jweil/gcc48/trunk/gcc/fortran/trans-intrinsic.c:6303
0x639461 gfc_conv_function_expr
        /home/jweil/gcc48/trunk/gcc/fortran/trans-expr.c:5127
0x63b4e8 gfc_conv_expr(gfc_se*, gfc_expr*)
        /home/jweil/gcc48/trunk/gcc/fortran/trans-expr.c:5834
0x63b99c gfc_conv_expr_reference(gfc_se*, gfc_expr*)
        /home/jweil/gcc48/trunk/gcc/fortran/trans-expr.c:5963
0x65ecb5 gfc_trans_transfer(gfc_code*)
        /home/jweil/gcc48/trunk/gcc/fortran/trans-io.c:2246
0x5f99da trans_code
        /home/jweil/gcc48/trunk/gcc/fortran/trans.c:1510
0x5f9b37 gfc_trans_code_cond(gfc_code*, tree_node*)
        /home/jweil/gcc48/trunk/gcc/fortran/trans.c:1565
0x65dd2e build_dt
        /home/jweil/gcc48/trunk/gcc/fortran/trans-io.c:1831
0x65de0a gfc_trans_write(gfc_code*)
        /home/jweil/gcc48/trunk/gcc/fortran/trans-io.c:1870
0x5f9953 trans_code
        /home/jweil/gcc48/trunk/gcc/fortran/trans.c:1482
0x5f9b56 gfc_trans_code(gfc_code*)
        /home/jweil/gcc48/trunk/gcc/fortran/trans.c:1573
0x628ccb gfc_generate_function_code(gfc_namespace*)
        /home/jweil/gcc48/trunk/gcc/fortran/trans-decl.c:5353
0x5f9b9a gfc_generate_code(gfc_namespace*)
        /home/jweil/gcc48/trunk/gcc/fortran/trans.c:1590
0x59b241 translate_all_program_units
        /home/jweil/gcc48/trunk/gcc/fortran/parse.c:4467
0x59b8a7 gfc_parse_file()
        /home/jweil/gcc48/trunk/gcc/fortran/parse.c:4681
0x5e67f4 gfc_be_parse_file
        /home/jweil/gcc48/trunk/gcc/fortran/f95-lang.c:191
Comment 3 janus 2012-10-10 08:28:29 UTC
(In reply to comment #1)
> 
>       call DestroyNode (theNode, lstatus )
>                         1
> Error: Actual argument for 'thenode' must be a pointer at (1)
> 
> which seems weird (AFAICT theNode is a pointer).

I agree that this error looks fishy. 'theNode' is clearly declared as POINTER, and the error only occurs if the call is inside a SELECT TYPE statement. Here is a reduced test case:


  implicit none

  type treeNode
  end type

  class(treeNode), pointer :: theNode
  logical :: lstatus
  
  select type( theNode )
  class is (treeNode)
    call DestroyNode (theNode, lstatus )
  end select
  
contains

  subroutine DestroyNode( theNode, lstatus )
    class(treeNode), pointer :: theNode
    logical, intent(out) :: lstatus
  end subroutine
  
end


Seems to be a regression on trunk.
Comment 4 janus 2012-10-10 08:34:10 UTC
In summary, we have two bugs here:

1) The ICE in comment 2, which happens with all gfortran versions from 4.5 to trunk.

2) The error message in comment 3, which only happens with trunk (and therefore is a regression).
Comment 5 janus 2012-10-10 16:35:23 UTC
(In reply to comment #4) 
> 1) The ICE in comment 2, which happens with all gfortran versions from 4.5 to
> trunk.

The ICE can be fixed by the following patch:

Index: gcc/fortran/trans-intrinsic.c
===================================================================
--- gcc/fortran/trans-intrinsic.c	(revision 192159)
+++ gcc/fortran/trans-intrinsic.c	(working copy)
@@ -5732,8 +5732,6 @@ gfc_conv_associated (gfc_se *se, gfc_expr *expr)
   gfc_init_se (&arg1se, NULL);
   gfc_init_se (&arg2se, NULL);
   arg1 = expr->value.function.actual;
-  if (arg1->expr->ts.type == BT_CLASS)
-    gfc_add_data_component (arg1->expr);
   arg2 = arg1->next;
 
   /* Check whether the expression is a scalar or not; we cannot use
@@ -5755,7 +5753,10 @@ gfc_conv_associated (gfc_se *se, gfc_expr *expr)
 	      && arg1->expr->symtree->n.sym->attr.dummy)
 	    arg1se.expr = build_fold_indirect_ref_loc (input_location,
 						       arg1se.expr);
-	  tmp2 = arg1se.expr;
+	  if (arg1->expr->ts.type == BT_CLASS)
+	      tmp2 = gfc_class_data_get (arg1se.expr);
+	  else
+	    tmp2 = arg1se.expr;
         }
       else
         {
Comment 6 janus 2012-10-10 17:31:45 UTC
(In reply to comment #4)
> 2) The error message in comment 3, which only happens with trunk (and therefore
> is a regression).

This can be fixed by the following:

Index: gcc/fortran/match.c
===================================================================
--- gcc/fortran/match.c	(revision 192159)
+++ gcc/fortran/match.c	(working copy)
@@ -5257,12 +5257,14 @@ select_class_set_tmp (gfc_typespec *ts)
   gfc_get_sym_tree (name, gfc_current_ns, &tmp, false);
   gfc_add_type (tmp->n.sym, ts, NULL);
 
-/* Copy across the array spec to the selector.  */
+  tmp->n.sym->attr.pointer
+	    = CLASS_DATA (select_type_stack->selector)->attr.class_pointer;
+
+  /* Copy across the array spec to the selector.  */
   if (select_type_stack->selector->ts.type == BT_CLASS
       && (CLASS_DATA (select_type_stack->selector)->attr.dimension
 	  || CLASS_DATA (select_type_stack->selector)->attr.codimension))
     {
-      tmp->n.sym->attr.pointer = 1;
       tmp->n.sym->attr.dimension
 		= CLASS_DATA (select_type_stack->selector)->attr.dimension;
       tmp->n.sym->attr.codimension



However, I really wonder what caused this regression. On a quick glance, the only patch concerning SELECT TYPE on trunk was the commit for PR41600. And I don't directly see how this would cause the regression.
Comment 7 janus 2012-10-10 17:33:41 UTC
Here is a variant of the test case in comment 3, which for some strange reason fails also with 4.7:


  implicit none

  type treeNode
  end type

  class(treeNode), pointer :: theNode
  logical :: lstatus
  
  select type( theNode )
  type is (treeNode)
    call DestroyNode (theNode, lstatus )
  class is (treeNode)
    call DestroyNode (theNode, lstatus )
  end select
  
contains

  subroutine DestroyNode( theNode, lstatus )
    type(treeNode), pointer :: theNode
    logical, intent(out) :: lstatus
  end subroutine

end
Comment 8 janus 2012-11-26 10:30:18 UTC
Author: janus
Date: Mon Nov 26 10:30:12 2012
New Revision: 193809

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=193809
Log:
2012-11-26  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/54881
	* match.c (select_derived_set_tmp,select_class_set_tmp): Removed and
	unified into ...
	(select_type_set_tmp): ... this one. Set POINTER argument according to
	selector.
	* trans-intrinsic.c (gfc_conv_associated): Use 'gfc_class_data_get'
	instead of 'gfc_add_data_component'.

2012-11-26  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/54881
	* gfortran.dg/associated_6.f90: New.
	* gfortran.dg/select_type_30.f03: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/associated_6.f90
    trunk/gcc/testsuite/gfortran.dg/select_type_30.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/match.c
    trunk/gcc/fortran/trans-intrinsic.c
    trunk/gcc/testsuite/ChangeLog
Comment 9 janus 2012-11-26 10:33:30 UTC
r193809 fixes both problems on trunk. Closing.

Thanks for the bug report!