GCC Bugzilla has been upgraded from version 4.4.9 to 5.0rc3. If you see any problem, please report it to bug 64968.
Bug 35820 - internal compiler error with nested FORALL
Summary: internal compiler error with nested FORALL
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: ---
Assignee: Mikael Morin
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: 32834
  Show dependency treegraph
 
Reported: 2008-04-03 18:40 UTC by Dick Hendrickson
Modified: 2008-11-08 08:39 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.4.0
Last reconfirmed: 2008-04-03 22:27:15


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dick Hendrickson 2008-04-03 18:40:42 UTC
The following program causes an internal compiler error.
Each of the three subroutines causes an ICE.  The ICE moves
around or goes away when I try to simplify the test much
more.

! fails on Windows XP
! gcc version 4.4.0 20080312 (experimental) [trunk revision 133139]

Dick Hendrickson

      MODULE TESTS


      IMPLICIT CHARACTER(LEN=9) (B)
      IMPLICIT CHARACTER(LEN=1) (C)
      IMPLICIT CHARACTER(LEN=9) (E)
      IMPLICIT CHARACTER(LEN=1) (F)
      IMPLICIT REAL(KIND=4)            (R)
      IMPLICIT REAL(KIND=8)            (D)
      IMPLICIT INTEGER         (I)
      IMPLICIT INTEGER         (H)
      IMPLICIT LOGICAL         (L)
      IMPLICIT LOGICAL         (G)
      IMPLICIT COMPLEX(KIND=4)         (Z)
      IMPLICIT COMPLEX(KIND=8)         (Y)
      IMPLICIT CHARACTER (A,J,K,M,N,O,P,S,T,U,V,W)
      INTEGER,PARAMETER,PUBLIC  ::  NF_KV = KIND(1)

      INTEGER,PARAMETER,PUBLIC  ::  I1_KV = KIND(1)
      INTEGER,PARAMETER,PUBLIC  ::  I2_KV = I1_KV
     
      INTEGER,PARAMETER,PUBLIC  ::  R1_KV = KIND(1.0)
      INTEGER,PARAMETER,PUBLIC  ::  R2_KV = KIND(1.0D0)

      INTEGER,PARAMETER,PUBLIC  ::  L1_KV = KIND(.TRUE.)
      INTEGER,PARAMETER,PUBLIC  ::  L2_KV = L1_KV

      INTEGER,PARAMETER,PUBLIC  ::  C1_KV = KIND('A')
      INTEGER,PARAMETER,PUBLIC  ::  C2_KV = C1_KV
      INTEGER, PARAMETER, PUBLIC  ::  NPBIG=1000
      INTEGER, PARAMETER, PUBLIC  ::  NPSIZE = 5
      INTEGER, PARAMETER, PUBLIC  ::  NPBIGM = NPBIG-1
      INTEGER, PUBLIC, PARAMETER  ::
     $       NP0 = 0,
     $       NP1 = 1,
     $       NP2 = 2,
     $       NP3 = 3,
     $       NP4 = 4,
     $       NP5 = 5,
     $       MP1 = -1,
     $       MP2 = -2,
     $       MP3 = -3,
     $       MP4 = -4,
     $       MP5 = -5
      INTEGER, SAVE ::  NF0,NF1,NF2,NF3,NF4,NF5,
     $                             NF6,NF7,NF8,NF9,NF10,
     $                             NFBIGM,NFBIG,
     $                             MF1,MF2,MF3,MF4,MF5,
     $                             MF6,MF7,MF8,MF9,MF10,
     $                             MFBIGM,MFBIG
      CHARACTER, PRIVATE :: I,J,K,L,M,N
      INTEGER, PRIVATE :: J1,J2,J3,J4,J5,J6,J7,JJJ
      INTEGER, PRIVATE :: ISTAT
      INTEGER(NF_KV), PRIVATE, PARAMETER  ::
     $ NP6=6, NP7=7, NP8=8, NP9=9, NP10=10,
     $ MP6=-6, MP7=-7, MP8=-8, MP9=-9, MP10=-10
      CONTAINS
      SUBROUTINE SA0136(RDA,IDA,BDA)
      REAL(R1_KV) RDA(10)
      INTEGER(I1_KV) IDA(10,9)
      CHARACTER(9,C1_KV) BDA(10,9,5)
      INTEGER(I1_KV) ICA(10,9)
      COMMON /IF/ IF(NPBIG*NPSIZE)
      EQUIVALENCE (ICA,IF(1))
      REAL(R1_KV) RCA(10)
      COMMON /RF/ RF(NPBIG*NPSIZE)
      EQUIVALENCE (RCA,RF(1))
      CHARACTER(9,C1_KV) BCA(10,9,5)
      COMMON /BF/ BF(NPBIG*NPSIZE)
      EQUIVALENCE (BCA,BF(1))
!  I N I T I A L I Z A T I O N  S E C T I O N
      RDA = RCA
      IDA = ICA
      BDA = BCA
!  T E S T  S T A T E M E N T S
      FORALL (J1 = 1:10)
        RDA(J1) = RCA(J1) + 1.0_R1_KV
        FORALL (J2 = 1:9)
          FORALL (J3 = 1:5)
            BDA(J1,J2,J3) = "X"//BCA(J1,J2,J3)
          END FORALL
          IDA(J1,J2) = ICA(J1,J2) + 1
        END FORALL
      ENDFORALL
      END SUBROUTINE
      SUBROUTINE SA0137(RDA,YDA,BDA,IDA,NDS10,NDS9)
      INTEGER(NF_KV) :: NDS10
      INTEGER(NF_KV) :: NDS9
      REAL(R1_KV) RDA(NF10)
      COMPLEX(R2_KV) YDA(NDS10,NF9)
      CHARACTER(9,C1_KV) BDA(NF10,NDS9,NF5)
      INTEGER(I1_KV) IDA(NF10)
      COMPLEX(R2_KV) YCA(10,9)
      COMMON /YF/ YF(NPBIG*NPSIZE)
      EQUIVALENCE (YCA,YF(1))
      REAL(R1_KV) RCA(10)
      COMMON /RF/ RF(NPBIG*NPSIZE)
      EQUIVALENCE (RCA,RF(1))
      INTEGER(I1_KV) ICA(10)
      COMMON /IF/ IF(NPBIG*NPSIZE)
      EQUIVALENCE (ICA,IF(1))
      CHARACTER(9,C1_KV) BCA(10,9,5)
      COMMON /BF/ BF(NPBIG*NPSIZE)
      EQUIVALENCE (BCA,BF(1))
!  I N I T I A L I Z A T I O N  S E C T I O N
      RDA(1:10) = RCA
      YDA(1:10,1:9) = YCA
      BDA(1:10,1:9,1:5) = BCA
      IDA(1:10) = ICA
!  T E S T  S T A T E M E N T S
      FORALL (J1 = NF1:NF10)
        RDA(J1) = RCA(J1) + 1.0_R1_KV
        FORALL (J2 = NF1:NF9)
          FORALL (J3 = NF1:NF5)
            BDA(J1,J2,J3) = "X"//BCA(J1,J2,J3)
          END FORALL
          YDA(J1,J2) = YCA(J1,J2) + 1
        END FORALL
        IDA(J1) = ICA(J1) + 1
      ENDFORALL
      END SUBROUTINE
      SUBROUTINE SA0138(RDA,YDA,BDA,IDA,NDS10,NDS9)
      INTEGER(NF_KV) :: NDS10
      INTEGER(NF_KV) :: NDS9
      REAL(R1_KV) RDA(NF10)
      COMPLEX(R2_KV) YDA(NDS10,NF9)
      CHARACTER(9,C1_KV) BDA(NF10,NDS9,NF5)
      INTEGER(I1_KV) IDA(NF10)
      COMPLEX(R2_KV) YCA(10,9)
      COMMON /YF/ YF(NPBIG*NPSIZE)
      EQUIVALENCE (YCA,YF(1))
      REAL(R1_KV) RCA(10)
      COMMON /RF/ RF(NPBIG*NPSIZE)
      EQUIVALENCE (RCA,RF(1))
      CHARACTER(9,C1_KV) BCA(10,9,5)
      COMMON /BF/ BF(NPBIG*NPSIZE)
      EQUIVALENCE (BCA,BF(1))
      INTEGER(I1_KV) ICA(10)
      COMMON /IF/ IF(NPBIG*NPSIZE)
      EQUIVALENCE (ICA,IF(1))
!  I N I T I A L I Z A T I O N  S E C T I O N
      RDA(1:10) = RCA
      YDA(1:10,1:9) = YCA
      BDA(1:10,1:9,1:5) = BCA
      IDA(1:10) = ICA
      J1 = 6
      J2 = 7
      J3 = 8
!  T E S T  S T A T E M E N T S
      FORALL (J1 = NF1:NF10)
        RDA(J1) = RDA(J1) + 1.0_R1_KV
        IDA(J1) = IDA(J1) + 1
        FORALL (J2 = NF1:NF9)
          FORALL (J3 = NF1:NF5) BDA(J1,J2,J3) = "X"//BDA(J1,J2,J3)
          YDA(J1,J2) = YDA(J1,J2) + 1
        END FORALL
        IDA(J1) = IDA(J1) + 1
      ENDFORALL
      END SUBROUTINE
      END MODULE TESTS


gfortran%gfortran sa0136.f
f951.exe: 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.
Comment 1 Dominique d'Humieres 2008-04-03 20:30:52 UTC
The code compiles fine on (powerpc|i686)-apple-darwin9. Would it be possible to check how the executable works?

Comment 2 Dick Hendrickson 2008-04-03 22:12:52 UTC
Subject: Re:  internal compiler error with forall

On Thu, Apr 3, 2008 at 3:30 PM, dominiq at lps dot ens dot fr
<gcc-bugzilla@gcc.gnu.org> wrote:
>
>
>  ------- Comment #1 from dominiq at lps dot ens dot fr  2008-04-03 20:30 -------
>  The code compiles fine on (powerpc|i686)-apple-darwin9. Would it be possible to
>  check how the executable works?

Not easily, from my point of view.  This is an isolated part of a
large test suite.  I
spent a couple of half days getting it down to this level.  The
problem is that the
ICE moves around if I do anything.  I've deleted about 160 of the original set
of tests for this isolation.  If I leave the 160 in and delete only 2 of the 3
subroutines I sent in the results are

With SA0136 "not removed"

gfortran%try_gfortranr s_sa0
working\s_sa0_mods.f
working\s_sa0_tests.f
working\s_sa0_exts.f
        1 file(s) copied.
rem.f: In function 'sa0160':
rem.f:5327: internal compiler error: Segmentation fault
[snip]

With SA0137 "not removed"

gfortran%try_gfortranr s_sa0
working\s_sa0_mods.f
working\s_sa0_tests.f
working\s_sa0_exts.f
        1 file(s) copied.
rem.f: In function 'sa0131':
rem.f:4412: internal compiler error: Segmentation fault
[snip]

With SA0138 "not removed"

gfortran%try_gfortranr s_sa0
working\s_sa0_mods.f
working\s_sa0_tests.f
working\s_sa0_exts.f
        1 file(s) copied.
rem.f: In function 'sa0128':
rem.f:4325: internal compiler error: Segmentation fault
[snip]


That is, the ICE appears in 3 different places, depending on which "bad"
subroutine I leave in the test set.  If I delete the 3 bad routines,
the other 160
all work correctly.

I'm reluctant to send in the whole set for two reasons.  It's large, the 160
subroutines are 190000 characters or so and they need a substantial
amount of structure code to work.  Also, the suite is my bread-and-butter
product and I'm reluctant to put part of it in the public domain.

If no one can reproduce the problem on a Windows machine, I can try to
make an executable that fails.

Dick Hendrickson
>
>
>  --
>
>
>  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35820
>
>  ------- You are receiving this mail because: -------
>  You reported the bug, or are watching the reporter.
>
Comment 3 Tobias Burnus 2008-04-03 22:27:15 UTC
Confirm. While I do not get any crash like Dominique, valgrind shows that that there is a problem:

==20532== Invalid write of size 8
==20532==    at 0x463933: resolve_code (resolve.c:5902)
==20532==    by 0x4661DB: gfc_resolve_blocks (resolve.c:5988)

==20532== Invalid read of size 8
==20532==    at 0x45B12E: gfc_resolve_assign_in_forall (resolve.c:5744)
==20532==    by 0x463A5C: resolve_code (resolve.c:5833)

I cannot look at the source as the computer where I've build gfortran is currently off.
Comment 4 Tobias Burnus 2008-04-04 09:40:38 UTC
I think the problem are related to nested FORALLs. The following is enough to              cause the valgrind error (add the needed definitions from comment 0). If I comment either the RDA(J1) assignment in the outer FORALL or the inner FORALL, valgrind finds no error.

      FORALL (J1 = 1:10)
        RDA(J1) = RCA(J1) + 1.0_R1_KV
        FORALL (J2 = 1:9)
          IDA(J1,J2) = ICA(J1,J2) + 1
        END FORALL
      ENDFORALL

The line shown by valgrind is:
==629==    at 0x463A23: resolve_code (resolve.c:5902)

If I go to the source, this is:
      /* Record the current FORALL index.  */
      var_expr[nvar] = gfc_copy_expr (fa->var);

where of the function gfc_resolve_forall (i.e. the function has been inlined in  resolve_code).

I have somehow the feeling that total_var is too small as for forall_save != 0 the size is not properly set. I think the problem is that it is that forall_save has a nonzero value as soon as "RDA(J1) =" is encountered and thus the size is not properly increased when the inner FORALL is encountered. If one swaps the order of "RDA(J1) =" and the inner FOREACH loop, valgrind finds not error.
Comment 5 Paul Thomas 2008-05-01 17:40:18 UTC
Tobias,

Does this do the job?

Paul

Index: gcc/fortran/resolve.c
===================================================================
*** gcc/fortran/resolve.c       (revision 134835)
--- gcc/fortran/resolve.c       (working copy)
*************** gfc_resolve_forall (gfc_code *code, gfc_
*** 5910,5915 ****
--- 5910,5918 ----
    /* May call gfc_resolve_forall to resolve the inner FORALL loop.  */
    gfc_resolve_blocks (code->block, ns);
  
+   if (forall_save)
+     return;
+ 
    /* Free VAR_EXPR after the whole FORALL construct resolved.  */
    for (i = 0; i < total_var; i++)
      gfc_free_expr (var_expr[i]);

Comment 6 Paul Thomas 2008-05-01 19:47:56 UTC
> Does this do the job?

BTW It breaks forall_7.f90 because it does not distinguish multiple sub-blocks but, I suspect it cures the segfault/memory problem.

This needs a more intelligent approach to storing the iterator variables.

Cheers

Paul
Comment 7 Paul Thomas 2008-10-22 15:30:49 UTC
(In reply to comment #3)
> Confirm. While I do not get any crash like Dominique, valgrind shows that that
> there is a problem:
> 
> ==20532== Invalid write of size 8
> ==20532==    at 0x463933: resolve_code (resolve.c:5902)
> ==20532==    by 0x4661DB: gfc_resolve_blocks (resolve.c:5988)
> 
> ==20532== Invalid read of size 8
> ==20532==    at 0x45B12E: gfc_resolve_assign_in_forall (resolve.c:5744)
> ==20532==    by 0x463A5C: resolve_code (resolve.c:5833)
> 
> I cannot look at the source as the computer where I've build gfortran is
> currently off.

Tobias,

How do you extract this diagnostic from valgrind?  I have never used it before but found it rolled into FC9.

Cheers

Paul  

Comment 8 Tobias Burnus 2008-10-22 16:27:18 UTC
> > Confirm. While I do not get any crash like Dominique, valgrind shows that
> > there is a problem:
>
> How do you extract this diagnostic from valgrind?  I have never used it before
> but found it rolled into FC9.

Well, that is simple: Run gfortran with the -v option, search for the line where f951 is called, copy that line and run

valgrind <insert the copied line here>

That's all what is needed, you might try some special options, but most of the time the defaults are sufficient.
(Note: Whether writes/reads are diagnosed to be invalid depend on the exact memory layout, sometimes small changes on a program make valgrind fail to detect a problem, though most of the time the diagnosis is quite stable.)

==31901== Invalid write of size 8
==31901==    at 0x470F8E: gfc_resolve_forall (resolve.c:6264)
==31901==    by 0x47204C: resolve_code (resolve.c:6523)

The line in question is:

      /* Record the current FORALL index.  */
      var_expr[nvar] = gfc_copy_expr (fa->var);

To run f951 in the debugger, one simply run then
  gdb --args <copy f951 line here>
Comment 9 Mikael Morin 2008-10-28 14:06:21 UTC
So that they are not lost, patches are here:
http://gcc.gnu.org/ml/fortran/2008-10/msg00153.html
http://gcc.gnu.org/ml/fortran/2008-10/msg00181.html
http://gcc.gnu.org/ml/fortran/2008-10/msg00212.html

See the follow-up threads and the mailing list archive for comments.
Comment 10 Mikael Morin 2008-10-31 15:38:45 UTC
Subject: Bug 35820

Author: mikael
Date: Fri Oct 31 15:37:17 2008
New Revision: 141496

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141496
Log:

2008-10-31  Mikael Morin  <mikael.morin@tele2.fr>

	PR fortran/35820
	* resolve.c (gfc_count_forall_iterators): New function.
	(gfc_resolve_forall): Use gfc_count_forall_iterators to evaluate 
	the needed memory amount to allocate. Don't forget to free allocated 
	memory.  Add an assertion to check for memory leaks. 

2008-10-16  Mikael Morin  <mikael.morin@tele2.fr>

	PR fortran/35820
	* gfortran.dg/nested_forall_1.f: New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/nested_forall_1.f
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/testsuite/ChangeLog

Comment 11 Paul Thomas 2008-11-06 06:19:35 UTC
Mikael,

I'll assign this to you, since it needs to be marked as fixed or applied to 4.3 and marked as fixed - I forget which was agreed.

If you do not have a 4.3 tree up and running, I could do the honours for you.

Cheers

Paul
Comment 12 Paul Thomas 2008-11-08 08:39:51 UTC
Fixed on trunk and 4.3

Thanks for the report

Paul and Mikael
Comment 13 Paul Thomas 2008-11-08 08:40:06 UTC
Subject: Bug 35820

Author: pault
Date: Sat Nov  8 08:38:42 2008
New Revision: 141707

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141707
Log:
2008-11-08  Mikael Morin  <mikael.morin@tele2.fr>

	PR fortran/35820
	* resolve.c (gfc_count_forall_iterators): New function.
	(gfc_resolve_forall): Use gfc_count_forall_iterators to evaluate 
	the needed memory amount to allocate. Don't forget to free allocated 
	memory.  Add an assertion to check for memory leaks. 

2008-11-08  Mikael Morin  <mikael.morin@tele2.fr>

	PR fortran/35820
	* gfortran.dg/nested_forall_1.f: New test.

Added:
    branches/gcc-4_3-branch/gcc/testsuite/gfortran.dg/nested_forall_1.f
Modified:
    branches/gcc-4_3-branch/gcc/fortran/ChangeLog
    branches/gcc-4_3-branch/gcc/fortran/resolve.c
    branches/gcc-4_3-branch/gcc/testsuite/ChangeLog