Bug 31213 - ICE on valid code with gfortran
Summary: ICE on valid code with gfortran
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Paul Thomas
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: 32834 33998
  Show dependency treegraph
 
Reported: 2007-03-16 11:43 UTC by Joost VandeVondele
Modified: 2007-12-16 11:42 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.1.3 4.2.0 4.3.0
Last reconfirmed: 2007-11-16 20:34:50


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joost VandeVondele 2007-03-16 11:43:40 UTC
A recent gfortran ICEs on the following code:

module mykinds
   implicit none
   integer, parameter :: ik1 = selected_int_kind(2)
   integer, parameter :: ik2 = selected_int_kind(4)
   integer, parameter :: dp = selected_real_kind(15,300)
end module mykinds

module spec_xpr
   use mykinds
   implicit none
   integer(ik2) c_size
   contains
      pure function tricky(str,ugly)
         character(*), intent(in) :: str
         integer(ik1) ia_ik1(len(str))
         interface yoagly
            pure function ugly(n)
               use mykinds
               implicit none
               integer, intent(in) :: n
               complex(dp) ugly(3*n+2)
            end function ugly
         end interface yoagly
         logical la(size(yoagly(size(ia_ik1))))
         integer i
         character(tricky_helper((/(.TRUE.,i=1,size(la))/))+c_size) tricky

         tricky = repeat('X',len(tricky))
      end function tricky

      pure function tricky_helper(lb)
         logical, intent(in) :: lb(:)
         integer tricky_helper

         tricky_helper = 2*size(lb)+3
      end function tricky_helper
end module spec_xpr

module xtra_fun
   implicit none
   contains
      pure function butt_ugly(n)
         use mykinds
         implicit none
         integer, intent(in) :: n
         complex(dp) butt_ugly(3*n+2)
         real(dp) pi, sq2

         pi = 4*atan(1.0_dp)
         sq2 = sqrt(2.0_dp)
         butt_ugly = cmplx(pi,sq2,dp)
      end function butt_ugly
end module xtra_fun

program spec_test
   use mykinds
   use spec_xpr
   use xtra_fun
   implicit none

   c_size = 5
   write(*,'(1x,i0)') len(tricky('Help me',butt_ugly))
   write(*,'(1x,a)') tricky('Help me',butt_ugly)
end program spec_test
Comment 1 Tobias Burnus 2007-03-21 17:15:41 UTC
aad.f90: In function 'tricky':
aad.f90:24: internal compiler error: in gfc_get_symbol_decl, at fortran/trans-decl.c:877

Compiles with NAG f95 and g95, ICEs with ifort and sunf95.
Comment 2 Francois-Xavier Coudert 2007-03-24 20:53:03 UTC
Reduced testcase:

function tricky(ugly)
  interface yoagly
    pure function ugly()
      complex ugly(2)
    end function ugly
  end interface yoagly

  logical la(size(yoagly()))
  print *, size(la)
end function tricky

I would have bet that this would be fixed when Paul fixed PR31215, because it's an ICE in the same place, but it appears it isn't fixed. Paul, since the previous PRs were really related, you might understand this one easily?
Comment 3 Paul Thomas 2007-04-02 14:43:22 UTC
(In reply to comment #2)

> an ICE in the same place, but it appears it isn't fixed. Paul, since the
> previous PRs were really related, you might understand this one easily?

I had hoped so, but the problem here turns out to be in resolution.  I can fix the reduced testcase but the original is still eluding me.

Paul
Comment 4 Jerry DeLisle 2007-07-19 02:19:58 UTC
Paul, in response to your recent concern on the ml, I am going to start chipping at this.
Comment 5 Jerry DeLisle 2007-09-20 03:25:08 UTC
Un-assigning myself.  No time at the moment  
Comment 6 Paul Thomas 2007-11-16 20:34:50 UTC
The reduced testcase of #2 is fixed by:

Index: gcc/fortran/resolve.c
===================================================================
*** gcc/fortran/resolve.c       (revision 129882)
--- gcc/fortran/resolve.c       (working copy)
*************** resolve_generic_f0 (gfc_expr *expr, gfc_
*** 1418,1423 ****
--- 1418,1425 ----
          else if (s->result != NULL && s->result->as != NULL)
            expr->rank = s->result->as->rank;

+         gfc_set_sym_referenced (expr->value.function.esym);
+
          return MATCH_YES;
        }

ie. The specific function was not getting set as referenced in this case.

The original testcase now gets to:

$ /irun/bin/gfortran -fdump-tree-original pr31213.f90
pr31213.f90: In function 'spec_test':
pr31213.f90:62: internal compiler error: in make_decl_rtl, at varasm.c:1263

This is odd because butt_ugly is marked as DECL_EXTERNAL and TREE_PUBLIC.

That's for tomorrow!

Paul
Comment 7 Paul Thomas 2007-11-16 21:22:28 UTC
Ah! ubound.51 is not declared anywhere in spec_test.

Paul
Comment 8 Paul Thomas 2007-11-17 17:18:40 UTC
(In reply to comment #7)
> Ah! ubound.51 is not declared anywhere in spec_test.

This comes about because the character length for 'tricky' depends on a characteristic of a variable, declared in tricky, that is not a dummy argument.  This is the nub of PR 33998 and I propose to transfer that part of this PR to 33998.

As well as the fix of #6, this PR needs a bit more:

The testcase below fails with....

/cygdrive/c/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccPP5t7g.o:pr31213.f90:(.tex
: undefined reference to `____MOD_i'
/cygdrive/c/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccPP5t7g.o:pr31213.f90:(.tex
: undefined reference to `____MOD_i'
/cygdrive/c/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccPP5t7g.o:pr31213.f90:(.tex
: undefined reference to `____MOD_i'
/cygdrive/c/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccPP5t7g.o:pr31213.f90:(.tex
: undefined reference to `____MOD_i'
/cygdrive/c/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccPP5t7g.o:pr31213.f90:(.tex
: undefined reference to `____MOD_i'
/cygdrive/c/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccPP5t7g.o:pr31213.f90:(.tex
: more undefined references to `____MOD_i' follow
collect2: ld returned 1 exit status

whereas the commented out line works. Evidently, something is awry with the referencing in array_constructor translation. 

Paul

module spec_xpr
   contains
      pure function tricky(ugly, j, lb)
         integer, intent(in) :: j
         logical, intent(in) :: lb(:)
         interface yoagly
            pure function ugly(n)
               integer, intent(in) :: n
               complex ugly(n)
            end function ugly
         end interface yoagly
!         character(tricky_helper(lb)) tricky
         character(tricky_helper((/(.true., i = 1, j)/))) tricky

         tricky = repeat('X',len(tricky))
      end function tricky

      pure function tricky_helper(lb)
         logical, intent(in) :: lb(:)
         integer tricky_helper

         tricky_helper = 2*size(lb)+3
      end function tricky_helper
end module spec_xpr

module xtra_fun
   contains
      pure function butt_ugly(n)
         integer, intent(in) :: n
         complex butt_ugly(n)
         butt_ugly = cmplx(0.,0.)
      end function butt_ugly
end module xtra_fun

program spec_test
   use spec_xpr
   use xtra_fun
   print *, tricky(butt_ugly,5,(/(.TRUE.,i = 1, 5)/))
end program spec_test

Comment 9 Paul Thomas 2007-11-22 09:30:21 UTC
Note that I posted an example to comp.lang.fortran that fails because of this bug: http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/6fea2c0227d1d430#657c2f8659a0024e

I'll get the patch submitted just as soon as all the wrinkles in my fix for PR33541 are sorted out.

Cheers

Paul
Comment 10 Paul Thomas 2007-12-11 16:17:50 UTC
I have now developed the patch for this and PR33998 to the point where the original testcase compiles.  It is, however, missing the interface transformation of the array_spec of 'yoagly' aka 'ugly' aka 'but_ugly'.  The result is that the descriptor for the result of 'yaogly' is missing the bounds, which causes the size to fail at runtime.

This missing element can be accomplished with the patch for PR33888, which is also cooking. I expect to be able to submit a combined patch by the end of this week.

Paul

Paul 
Comment 11 Paul Thomas 2007-12-16 11:34:29 UTC
Subject: Bug 31213

Author: pault
Date: Sun Dec 16 11:34:08 2007
New Revision: 130988

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=130988
Log:
2007-12-16  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/31213
	PR fortran/33888
	PR fortran/33998
	* trans-array.c (gfc_trans_array_constructor_value): If the
	iterator variable does not have a backend_decl, use a local
	temporary.
	(get_elemental_fcn_charlen): New function to map the character
	length of an elemental function onto its actual arglist.
	(gfc_conv_expr_descriptor): Call the above so that the size of
	the temporary can be evaluated.
	* trans-expr.c : Include arith.h and change prototype of
	gfc_apply_interface_mapping_to_expr to return void.  Change all
	references to gfc_apply_interface_mapping_to_expr accordingly.
	(gfc_free_interface_mapping): Free the 'expr' field.
	(gfc_add_interface_mapping): Add an argument for the actual
	argument expression. This is copied to the 'expr' field of the
	mapping.  Only stabilize the backend_decl if the se is present.
	Copy the character length expression and only add it's backend
	declaration if se is present.  Return without working on the
	backend declaration for the new symbol if se is not present.
	(gfc_map_intrinsic_function) : To simplify intrinsics 'len',
	'size', 'ubound' and 'lbound' and then to map the result.
	(gfc_map_fcn_formal_to_actual): Performs the formal to actual
	mapping for the case of a function found in a specification
	expression in the interface being mapped.
	(gfc_apply_interface_mapping_to_ref): Remove seen_result and
	all its references. Remove the inline simplification of LEN
	and call gfc_map_intrinsic_function instead.  Change the
	order of mapping of the actual arguments and simplifying
	intrinsic functions.  Finally, if a function maps to an
	actual argument, call gfc_map_fcn_formal_to_actual.
	(gfc_conv_function_call): Add 'e' to the call to
	gfc_add_interface_mapping.
	* dump-parse-tree.c (gfc_show_symbol_n): New function for
	diagnostic purposes.
	* gfortran.h : Add prototype for gfc_show_symbol_n.
	* trans.h : Add 'expr' field to gfc_add_interface_mapping.
	Add 'expr' to prototype for gfc_show_symbol_n.
	* resolve.c (resolve_generic_f0): Set specific function as
	referenced.

2007-12-16  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/31213
	PR fortran/33888
	PR fortran/33998
	* gfortran.dg/mapping_1.f90: New test.
	* gfortran.dg/mapping_2.f90: New test.
	* gfortran.dg/mapping_3.f90: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/mapping_1.f90
    trunk/gcc/testsuite/gfortran.dg/mapping_2.f90
    trunk/gcc/testsuite/gfortran.dg/mapping_3.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/dump-parse-tree.c
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans.h
    trunk/gcc/testsuite/ChangeLog

Comment 12 Paul Thomas 2007-12-16 11:42:53 UTC
Fixed on trunk

Paul