Bug 28885 - ICE passing components of array of derived type
Summary: ICE passing components of array of derived type
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: ---
Assignee: Paul Thomas
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-08-29 08:55 UTC by Drew McCormack
Modified: 2006-10-31 08:59 UTC (History)
2 users (show)

See Also:
Host:
Target: powerpc-apple-darwin8.8.0
Build: gcc version 4.2.0 20061007 (experimental)
Known to work:
Known to fail:
Last reconfirmed: 2006-08-29 15:49:37


Attachments
Provisional fix for the problem (377 bytes, patch)
2006-08-29 13:09 UTC, Paul Thomas
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Drew McCormack 2006-08-29 08:55:29 UTC
This ICE arises:


bug2.f90: In function ‘MAIN__’:
bug2.f90:30: internal compiler error: in gimplify_var_or_parm_decl, at gimplify.c:1665


when compiling the following code:


module modA
  implicit none
  private 
  public :: sub
  interface sub
    module procedure subA
    module procedure subB
  end interface
contains
  subroutine subA(key,a)
    integer, intent(out)    :: a(:) 
    character(*),intent(in) :: key
    a = 1   
  end subroutine
  subroutine subB(key,a)
    real, intent(out) :: a(:) 
    character(*),intent(in) :: key
    a = 1.0 
  end subroutine
end module

program test
  use modA
  type t  
    integer :: i
    real :: energy
  end type
  type (t) :: a(5) 
  call sub('blah',a%energy)
  call sub('blah',a%i)
end program 


The ICE only occurs if you call the overloaded subroutine multiple times in the same scope, for different components of the derived type. If you make one call for one component, compilation succeeds.
Comment 1 Paul Thomas 2006-08-29 13:05:41 UTC
(In reply to comment #0)
Drew,

You are really uncovering them! A simplified version of your testcase that produces the same fault is:

program test
  type t
    integer :: i
    integer :: j
  end type
  type (t) :: a(5) 
  call sub('one',a%j)
  call sub('two',a%i)
contains
  subroutine sub(key,a)
    integer, intent(out)    :: a(:) 
    character(*),intent(in) :: key
    a = 1   
  end subroutine
end program 

This produces the code below.  You will see that the first call uses a temporary for the integer array, atmp.5, and this in its turn points, via its data field to a temporary A.6.... which has disappeared off the face of the earth!  The second call points to A.10, which is properly declared in MAIN.

Now, if you get rid of the INTENT(OUT), the declarations to the temporaries are both present and the compilation proceeds correctly.  In fact, this could be a temporary workaround for your existing code.  Note that is is only components of arrays of derived types that will cause this problem (the fault is around line 1703 of trans-expr.c).

I have a patch regtesting right now. I will post it on this PR in just a moment.  If you are in a position to try it out, I would be very grateful.

Paul


MAIN__ ()
{
  struct t a[5];
  int4 A.10[5];
  struct array1_int4 atmp.9;

  _gfortran_set_std (70, 127, 0);
  {
    int4 S.11;

    {
      int4 D.935;

      atmp.5.dtype = 265;
      atmp.5.dim[0].stride = 1;
      atmp.5.dim[0].lbound = 0;
      atmp.5.dim[0].ubound = 4;
      atmp.5.data = (void *) &A.6;
      atmp.5.offset = 0;
      sub ("one", &atmp.5, 3);
      {
        int4 S.8;

        D.935 = -1;
        S.8 = 1;
        while (1)
          {
            if (S.8 > 5) goto L.2; else (void) 0;
            a[NON_LVALUE_EXPR <S.8> + -1].j = (*(int4[0:] *) atmp.5.data)[S.8 +
D.935];
            S.8 = S.8 + 1;
          }
        L.2:;
      }
    }
    {
      int4 D.941;

      atmp.9.dtype = 265;
      atmp.9.dim[0].stride = 1;
      atmp.9.dim[0].lbound = 0;
      atmp.9.dim[0].ubound = 4;
      atmp.9.data = (void *) &A.10;
      atmp.9.offset = 0;
      sub ("two", &atmp.9, 3);
      {
        int4 S.12;

        D.941 = -1;
        S.12 = 1;
        while (1)
          {
            if (S.12 > 5) goto L.3; else (void) 0;
            a[NON_LVALUE_EXPR <S.12> + -1].i = (*(int4[0:] *) atmp.9.data)[S.12
+ D.941];
            S.12 = S.12 + 1;
          }
        L.3:;
      }
    }
  }
}
Comment 2 Paul Thomas 2006-08-29 13:09:34 UTC
Created attachment 12148 [details]
Provisional fix for the problem

This is regtesting as I write but I have little doubt that this is incorrect.

Paul
Comment 3 Paul Thomas 2006-08-29 13:12:24 UTC
(In reply to comment #2)
> Created an attachment (id=12148) [edit]
> Provisional fix for the problem
> This is regtesting as I write but I have little doubt that this is incorrect.
> Paul

duuuhh! I have been staring too long at PRs:

I have little doubt that it is correct!

Paul
Comment 4 Paul Thomas 2006-08-29 15:49:37 UTC
Since I just posted a patch for it, I might as well assign it to myself!

Paul
Comment 5 Paul Thomas 2006-08-30 05:18:55 UTC
Subject: Bug 28885

Author: pault
Date: Wed Aug 30 05:18:36 2006
New Revision: 116578

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=116578
Log:
2006-08-30  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/28885
	REGRESSION FIX
	* trans-expr.c (gfc_conv_aliased_arg): Ensure that the temp
	declaration is retained for INTENT(OUT) arguments.

	PR fortran/28873
	REGRESSION FIX
	PR fortran/20067
	* resolve.c (resolve_generic_f): Make error message more
	comprehensible.
	(resolve_generic_s): Restructure search for specific procedures
	to be similar to resolve_generic_f and change to similar error
	message.  Ensure that symbol reference is refreshed, in case
	the search produces a NULL.
	(resolve_specific_s): Restructure search, as above and as
	resolve_specific_f. Ensure that symbol reference is refreshed,
	in case the search produces a NULL.

	PR fortran/25077
	PR fortran/25102
	* interface.c (check_operator_interface): Throw error if the
	interface assignment tries to change intrinsic type assigments
	or has less than two arguments.  Also, it is an error if an
	interface operator contains an alternate return.

	PR fortran/24866
	* parse.c (gfc_fixup_sibling_symbols): Do not modify the symbol
	if it is a dummy in the contained namespace.


2006-08-30  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/28885
	* gfortran.dg/aliasing_dummy_2.f90: New test.

	PR fortran/20067
	* gfortran.dg/generic_5.f90: Change error message.

	PR fortran/28873
	* gfortran.dg/generic_6.f90: New test.

	PR fortran/25077
	* gfortran.dg/redefined_intrinsic_assignment.f90: New test.

	PR fortran/25102
	* gfortran.dg/invalid_interface_assignment.f90: New test.

	PR fortran/24866
	* gfortran.dg/module_proc_external_dummy.f90: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/aliasing_dummy_2.f90
    trunk/gcc/testsuite/gfortran.dg/generic_6.f90
    trunk/gcc/testsuite/gfortran.dg/invalid_interface_assignment.f90
    trunk/gcc/testsuite/gfortran.dg/module_proc_external_dummy.f90
    trunk/gcc/testsuite/gfortran.dg/redefined_intrinsic_assignment.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/interface.c
    trunk/gcc/fortran/parse.c
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/generic_5.f90

Comment 6 Paul Thomas 2006-08-30 05:19:58 UTC
Subject: Bug 28885

Author: pault
Date: Wed Aug 30 05:19:34 2006
New Revision: 116579

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=116579
Log:
2006-08-30  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/28885
	REGRESSION FIX
	* trans-expr.c (gfc_conv_aliased_arg): Ensure that the temp
	declaration is retained for INTENT(OUT) arguments.

	PR fortran/28873
	REGRESSION FIX
	PR fortran/20067
	* resolve.c (resolve_generic_f): Make error message more
	comprehensible.
	(resolve_generic_s): Restructure search for specific procedures
	to be similar to resolve_generic_f and change to similar error
	message.  Ensure that symbol reference is refreshed, in case
	the search produces a NULL.
	(resolve_specific_s): Restructure search, as above and as
	resolve_specific_f. Ensure that symbol reference is refreshed,
	in case the search produces a NULL.

	PR fortran/25077
	PR fortran/25102
	* interface.c (check_operator_interface): Throw error if the
	interface assignment tries to change intrinsic type assigments
	or has less than two arguments.  Also, it is an error if an
	interface operator contains an alternate return.

	PR fortran/24866
	* parse.c (gfc_fixup_sibling_symbols): Do not modify the symbol
	if it is a dummy in the contained namespace.


2006-08-30  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/28885
	* gfortran.dg/aliasing_dummy_2.f90: New test.

	PR fortran/20067
	* gfortran.dg/generic_5.f90: Change error message.

	PR fortran/28873
	* gfortran.dg/generic_6.f90: New test.

	PR fortran/25077
	* gfortran.dg/redefined_intrinsic_assignment.f90: New test.

	PR fortran/25102
	* gfortran.dg/invalid_interface_assignment.f90: New test.

	PR fortran/24866
	* gfortran.dg/module_proc_external_dummy.f90: New test.

Added:
    branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/aliasing_dummy_2.f90
    branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/generic_6.f90
    branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/invalid_interface_assignment.f90
    branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/module_proc_external_dummy.f90
    branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/redefined_intrinsic_assignment.f90
Modified:
    branches/gcc-4_1-branch/gcc/fortran/ChangeLog
    branches/gcc-4_1-branch/gcc/fortran/interface.c
    branches/gcc-4_1-branch/gcc/fortran/parse.c
    branches/gcc-4_1-branch/gcc/fortran/resolve.c
    branches/gcc-4_1-branch/gcc/fortran/trans-expr.c
    branches/gcc-4_1-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/generic_5.f90

Comment 7 Paul Thomas 2006-08-30 05:31:00 UTC
Fixed on trunk and 4.1

Paul
Comment 8 Drew McCormack 2006-10-31 08:51:18 UTC
Unfortunately, though the fix did work for the example code, it doesn't seem to be general enough. In particular, if you change the example code to include just one extra subroutine call, the same compiler error arises. So, a fix is need that can handle any number of subroutine calls, not just one or two.

Here is new code demonstrating the error. It is simply the original code with one extra subroutine call:

program test
  type t  
    integer :: i
    integer :: j
  end type
  type (t) :: a(5) 
  call sub('one',a%j)
  call sub('two',a%i)
  call sub('two',a%i)
contains
  subroutine sub(key,a)
    integer, intent(out)    :: a(:) 
    character(*),intent(in) :: key
    a = 1   
  end subroutine
end program 
Comment 9 Andrew Pinski 2006-10-31 08:59:08 UTC
(In reply to comment #8)
> Here is new code demonstrating the error. It is simply the original code with
> one extra subroutine call:

That is the same as PR 29565.
So closing this bug as fixed.