Bug 48588 - [4.6/4.7 Regression] ICE (segfault) in gfc_get_nodesc_array_type
Summary: [4.6/4.7 Regression] ICE (segfault) in gfc_get_nodesc_array_type
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P4 normal
Target Milestone: 4.6.1
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on: 48692
Blocks:
  Show dependency treegraph
 
Reported: 2011-04-13 08:02 UTC by Andres Legarra
Modified: 2011-04-26 08:42 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-04-13 10:38:26


Attachments
source code (75.53 KB, application/octet-stream)
2011-04-13 08:02 UTC, Andres Legarra
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andres Legarra 2011-04-13 08:02:05 UTC
Created attachment 23971 [details]
source code

Compiling a fortran library compiled many other times with other compilers including gfortran 4.4.

Here is the command and output. For some reason I can't produce the preprocessed file


C:\Documents and Settings\legarra\Mes documents\gs3\zipable\software>gfortran -v -save-temps  -c ALliba
ll.f90
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=c:/program files/gfortran/bin/../libexec/gcc/i586-pc-mingw32/4.6.0/lto-wrapper.exe
Target: i586-pc-mingw32
Configured with: ../gcc-trunk/configure --prefix=/mingw --enable-languages=c,fortran --with-gmp=/home/b
rad/gfortran/dependencies --disable-werror --enable-threads --disable-nls --build=i586-pc-mingw32 --ena
ble-libgomp --enable-shared --disable-win32-registry --with-dwarf2 --disable-sjlj-exceptions --enable-l
to
Thread model: win32
gcc version 4.6.0 20110214 (experimental) [trunk revision 170140] (GCC)
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-mtune=pentium' '-march=pentium'
 c:/program files/gfortran/bin/../libexec/gcc/i586-pc-mingw32/4.6.0/f951.exe ALliball.f90 -quiet -dumpb
ase ALliball.f90 -mtune=pentium -march=pentium -auxbase ALliball -version -fintrinsic-modules-path c:/p
rogram files/gfortran/bin/../lib/gcc/i586-pc-mingw32/4.6.0/finclude -o ALliball.s
GNU Fortran (GCC) version 4.6.0 20110214 (experimental) [trunk revision 170140] (i586-pc-mingw32)
        compiled by GNU C version 4.6.0 20110214 (experimental) [trunk revision 170140], GMP version 4.
3.2, MPFR version 2.4.2, MPC version 0.8.2
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
GNU Fortran (GCC) version 4.6.0 20110214 (experimental) [trunk revision 170140] (i586-pc-mingw32)
        compiled by GNU C version 4.6.0 20110214 (experimental) [trunk revision 170140], GMP version 4.
3.2, MPFR version 2.4.2, MPC version 0.8.2
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
ALliball.f90:9521:0: 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 Tobias Burnus 2011-04-13 10:25:37 UTC
Valgrind shows:

==24723== Invalid read of size 4
==24723==    at 0x5C3338: gfc_get_nodesc_array_type (trans-types.c:1444)
==24723==    by 0x5C6DCC: gfc_sym_type (trans-types.c:2009)
==24723==    by 0x5C646C: gfc_get_function_type (trans-types.c:2607)
==24723==    by 0x584B0C: build_function_decl (trans-decl.c:1775)
==24723==    by 0x586666: gfc_create_function_decl (trans-decl.c:2340)
==24723==    by 0x587B4E: gfc_get_extern_function_decl (trans-decl.c:1582)
==24723==    by 0x59C93F: gfc_conv_procedure_call (trans-expr.c:1689)
==24723==    by 0x5B8C06: gfc_trans_call (trans-stmt.c:380)

The latter is:

      expr = as->lower[n];
      if (expr->expr_type == EXPR_CONSTANT)

Thus, it looks as if as->lower[n] == NULL.
Comment 2 Mikael Morin 2011-04-13 10:37:29 UTC
Confirmed on fairly recent trunk:
GNU Fortran (GCC) 4.7.0 20110404 (experimental)

Reduced testcase:

!!!!!!!!!!!!!!!!!!!!
MODULE LA_PRECISION
IMPLICIT NONE
INTEGER, PARAMETER :: dp = KIND(1.0D0)
END MODULE LA_PRECISION

module lapack90
INTERFACE
  SUBROUTINE DGESV_F90( A, B, IPIV, INFO )
    USE la_precision, ONLY: wp => dp
    IMPLICIT NONE
    INTEGER, INTENT(OUT), OPTIONAL         :: INFO
    INTEGER, INTENT(OUT), OPTIONAL, TARGET :: IPIV(:)
    REAL(WP), INTENT(IN OUT)               :: A(:,:), B(:,:)
  END SUBROUTINE DGESV_F90
END INTERFACE
end module

SUBROUTINE DGESV_F90( A, B, IPIV, INFO )
  USE la_precision, ONLY: wp => dp
  IMPLICIT NONE
  INTEGER, INTENT(OUT), OPTIONAL         :: INFO
  INTEGER, INTENT(OUT), OPTIONAL, TARGET :: IPIV(:)
  REAL(WP), INTENT(IN OUT)               :: A(:,:), B(:,:)
END SUBROUTINE DGESV_F90



MODULE DENSEOP
  USE LAPACK90
  implicit none
  integer, parameter :: r8 = SELECTED_REAL_KIND( 15, 307 )
  real(r8)::denseop_tol=1.d-50

  CONTAINS

  SUBROUTINE GEINV8 (x)
   real(r8)::x(:,:)
   real(r8),allocatable::x_o(:,:)
   allocate(x_o(size(x,1),size(x,1)))
   CALL dgesv_f90(x,x_o)
   x=x_o
  END SUBROUTINE GEINV8
END MODULE DENSEOP
!!!!!!!!!!!!!!!!!!!

It looks like a AS_DEFERRED vs AS_ASSUMED_SHAPE problem. 

Program received signal SIGSEGV, Segmentation fault.
gfc_get_nodesc_array_type (etype=0x8018540a8, as=0x801a0d440, 
    packed=PACKED_FULL, restricted=1 '\001')
    at /home/mik/gcc46/src/gcc/fortran/trans-types.c:1444
1444	      if (expr->expr_type == EXPR_CONSTANT)
(gdb) bt
#0  gfc_get_nodesc_array_type (etype=0x8018540a8, as=0x801a0d440, 
    packed=PACKED_FULL, restricted=1 '\001')
    at /home/mik/gcc46/src/gcc/fortran/trans-types.c:1444
#1  0x0000000000580482 in gfc_sym_type (sym=0x801a436c0)
    at /home/mik/gcc46/src/gcc/fortran/trans-types.c:2009
#2  0x0000000801a436c0 in ?? ()
#3  0x0000000801a90f70 in ?? ()
#4  0x0000000801a43500 in ?? ()
#5  0x0000000000000000 in ?? ()
(gdb) up
#1  0x0000000000580482 in gfc_sym_type (sym=0x801a436c0)
    at /home/mik/gcc46/src/gcc/fortran/trans-types.c:2009
2009		      type = gfc_get_nodesc_array_type (type, sym->as,
(gdb) p sym.name
$4 = 0x801844f58 "a"
(gdb) p *sym.as
$5 = {rank = 2, corank = 0, type = AS_DEFERRED, cotype = 0, lower = {0x0, 0x0, 
    0x0, 0x0, 0x0, 0x0, 0x0}, upper = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
  cray_pointee = 0 '\0', cp_was_assumed = 0 '\0'}
(gdb) p sym.attr.dummy
$6 = 1
Comment 3 Paul Thomas 2011-04-17 15:00:27 UTC
(In reply to comment #2)
> Confirmed on fairly recent trunk:
> GNU Fortran (GCC) 4.7.0 20110404 (experimental)
> 

The problem goes away if -fno-whole-file is used or the subroutine DGESV_F90 is removed.  Clearly there is some difference between the interface abstracted from the subroutine itself and that from the interface.

-fno-whole-file is a temporary workaround.

Paul
Comment 4 Tobias Burnus 2011-04-18 18:41:18 UTC
The problem is that when one goes via:

  gfc_get_extern_function_decl -> gfc_get_function_type

one has for the "a" argument of DGESV_F90 in gfc_sym_type the value:
  sym->as->type == AS_DEFERRED

However, the variable is not a pointer/deferred and thus gfc_is_nodesc_array returns that "a" is a descriptorless array ("return sym->as->type != AS_ASSUMED_SHAPE"), which is wrong.

The question is: Why is "a" AS_DEFERRED and not AS_ASSUMED_SHAPE?

 * * *

In principle, the changing of the "sym->as->type" to "AS_ASSUMED_SHAPE" is done in resolve.c's resolve_formal_arglist. If one sets a break point there, one sees that the function is called twice for "dgesv_f90" - but both times with proc->attr.if_source == IFSRC_IFBODY, once with proc->attr.use_assoc being 0 and once with it being 1.

If one has  -fno-whole-file,  resolve_formal_arglist is also called for "dgesv_f90" itself (IFSRC_DECL) - and thus as->type is correctly set. That's called via resolve_contained_functions

 * * *

My impression is that the resolving issues are an ordering problem in parse.c's 
gfc_parse_file. If one looks at the code, one finds:

loop:
  st = next_statement ();
  switch (st)
    {
    case ST_SUBROUTINE:
      if (gfc_option.flag_whole_file)
        goto prog_units;
      break;
    case ST_MODULE:
      break;
    }
  gfc_resolve (gfc_current_ns);
  if (s.state == COMP_MODULE)
        gfc_generate_module_code (gfc_current_ns);

  goto loop;

prog_units:
    gfc_global_ns_list = gfc_current_ns;
  goto loop;

  done:
    resolve_all_program_units (gfc_global_ns_list);
    translate_all_program_units (gfc_global_ns_list);
Comment 5 Tobias Burnus 2011-04-18 20:56:02 UTC
The following seems to mostly work. I think some double resolving could happen - thus, one might need to tweak resolve_all_program_units.

Paul & Mikael: What do you think?

Test-suite failures with the patch: gfortran.dg/entry_17.f90 (Extra -pedantic warnings), gfortran.dg/pr41011.f, gfortran.dg/auto_char_len_4.f90, gfortran.dg/func_decl_4.f90, gfortran.dg/generic_actual_arg.f90, gfortran.dg/global_references_1.f90, gfortran.dg/hollerith8.f90, gfortran.dg/bounds_temporaries_1.f90, 
gfortran.dg/integer_exponentiation_2.f90, gfortran.dg/g77/19990218-0.f, gfortran.dg/g77/970625-2.f, gfortran.dg/whole_file_16.f90, gfortran.dg/whole_file_18.f90, gfortran.dg/whole_file_2.f90, gfortran.dg/whole_file_20.f03)


--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -4411,6 +4411,8 @@ prog_units:
   else
     gfc_global_ns_list = gfc_current_ns;
 
+  gfc_resolve (gfc_current_ns);
+
   next = gfc_current_ns;
 
   pop_state ();
Comment 6 Mikael Morin 2011-04-19 10:27:29 UTC
(In reply to comment #5)
> The following seems to mostly work. I think some double resolving could happen
> - thus, one might need to tweak resolve_all_program_units.
Either this or we have to delay module code generation as well.
I can't tell whether double resolving is a problem. But I think resolving too early may be problematic as one can miss references to global procedures if they are defined later in the same file.
Comment 7 Tobias Burnus 2011-04-19 11:46:58 UTC
Patch: http://gcc.gnu.org/ml/fortran/2011-04/msg00206.html
Comment 8 Tobias Burnus 2011-04-19 16:26:21 UTC
Author: burnus
Date: Tue Apr 19 16:26:13 2011
New Revision: 172718

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172718
Log:
2011-04-19  Tobias Burnus  <burnus@net-b.de>

        PR fortran/48588
        * parse.c (resolve_all_program_units): Skip modules.
        (translate_all_program_units): Handle modules.
        (gfc_parse_file): Defer code generation for modules.

2011-04-19  Tobias Burnus  <burnus@net-b.de>

        PR fortran/48588
        * gfortran.dg/whole_file_33.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/whole_file_33.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/parse.c
    trunk/gcc/testsuite/ChangeLog
Comment 9 Tobias Burnus 2011-04-20 18:07:56 UTC
Author: burnus
Date: Wed Apr 20 18:07:52 2011
New Revision: 172782

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172782
Log:
2011-04-19  Tobias Burnus  <burnus@net-b.de>

        PR fortran/48588
        PR fortran/48692

        * module.c (fix_mio_expr): Commit created symbol.


Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/module.c
Comment 10 Tobias Burnus 2011-04-26 08:41:38 UTC
Author: burnus
Date: Tue Apr 26 08:41:31 2011
New Revision: 172953

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172953
Log:
2011-04-26  Tobias Burnus  <burnus@net-b.de>

        PR fortran/48588
        * parse.c (resolve_all_program_units): Skip modules.
        (translate_all_program_units): Handle modules.
        (gfc_parse_file): Defer code generation for modules.
        * module.c (fix_mio_expr): Commit created symbol.

2011-04-26  Tobias Burnus  <burnus@net-b.de>

        PR fortran/48588
        * gfortran.dg/whole_file_33.f90: New.


Added:
    branches/gcc-4_6-branch/gcc/testsuite/gfortran.dg/whole_file_33.f90
Modified:
    branches/gcc-4_6-branch/gcc/fortran/ChangeLog
    branches/gcc-4_6-branch/gcc/fortran/module.c
    branches/gcc-4_6-branch/gcc/fortran/parse.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Comment 11 Tobias Burnus 2011-04-26 08:42:48 UTC
FIXED on the trunk (4.7) and on the 4.6 branch (for 4.6.1).

Thanks for the report Andres!