When compiling the attached sources, I get Using built-in specs. COLLECT_GCC=gfortran COLLECT_LTO_WRAPPER=/archive/ohl/tools64/libexec/gcc/x86_64-unknown-linux-gnu/4.5.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: /home/ohl/archive/gcc/svn/configure --prefix=/archive/ohl/tools64/ --enable-languages=c,c++,fortran Thread model: posix gcc version 4.5.0 20100330 (experimental) (GCC) ward.f90:79:0: internal compiler error: in gfc_traverse_expr, at fortran/expr.c:3604 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions.
Created attachment 20261 [details] program that triggers the bug
confirmed.
Reduced test: module ward_lib implicit none type omega_procedures procedure(number_particles_out), nopass, pointer :: number_particles_out => NULL() procedure(number_flavor_states), nopass, pointer :: number_flavor_states => NULL() end type omega_procedures contains subroutine quantum_numbers2 (physical, unphysical) type(omega_procedures), intent(in) :: physical, unphysical integer, dimension(physical%number_particles_out(), & physical%number_flavor_states()) :: table_flavor_states end subroutine quantum_numbers2 end module ward_lib
Further reduced test that does not give an ICE, but several errors: [macbook] f90/bug% cat pr43591_red_1.f90 module ward_lib implicit none type omega_procedures procedure(number_particles_out), nopass, pointer :: number_particles_out => NULL() end type omega_procedures contains subroutine quantum_numbers2 () ! type(omega_procedures), intent(in) :: physical integer, dimension(physical%number_particles_out()) & :: table_flavor_states end subroutine quantum_numbers2 end module ward_lib [macbook] f90/bug% gfc pr43591_red_1.f90 pr43591_red_1.f90:14.31: integer, dimension(physical%number_particles_out()) & 1 Error: Expected another dimension in array declaration at (1) pr43591_red_1.f90:7.35: procedure(number_particles_out), nopass, pointer :: number_particles_out = 1 Error: Symbol 'number_particles_out' at (1) has no IMPLICIT type pr43591_red_1.f90:7.77: procedure(number_particles_out), nopass, pointer :: number_particles_out => 1 Error: Interface 'number_particles_out' of procedure pointer component 'number_particles_out' at (1) must be explicit If uncomment the commented line I get an ICE: #0 fancy_abort (file=0x100974ce0 "../../p_work/gcc/fortran/expr.c", line=3604, function=0x1009f4d80 "gfc_traverse_expr") at ../../p_work/gcc/diagnostic.c:762 #1 0x000000010002b86f in gfc_traverse_expr (expr=0x141815840, sym=0x0, func=0x100026480 <expr_check_typed_help>, f=0) at ../../p_work/gcc/fortran/expr.c:3604 #2 0x000000010002c5e7 in gfc_expr_check_typed (e=0x141815840, ns=0x142078600, strict=<value temporarily unavailable, due to optimizations>) at ../../p_work/gcc/fortran/expr.c:3767 #3 0x00000001000069f5 in gfc_match_array_spec (asp=0x100c8f140) at ../../p_work/gcc/fortran/array.c:310 #4 0x0000000100018bcf in match_attr_spec () at ../../p_work/gcc/fortran/decl.c:3044 #5 0x000000010001d137 in gfc_match_data_decl () at ../../p_work/gcc/fortran/decl.c:3730 #6 0x0000000100062f22 in match_word (str=<value temporarily unavailable, due to optimizations>, subr=0x10001d0d0 <gfc_match_data_decl>, old_locus=0x7fff5fbfd380) at ../../p_work/gcc/fortran/parse.c:65 #7 0x00000001000637ad in decode_statement () at ../../p_work/gcc/fortran/parse.c:283 #8 0x0000000100064dd5 in next_statement () at ../../p_work/gcc/fortran/parse.c:715 #9 0x000000010006613c in parse_spec (st=<value temporarily unavailable, due to optimizations>) at ../../p_work/gcc/fortran/parse.c:2549 #10 0x000000010006838d in parse_progunit (st=ST_ARITHMETIC_IF) at ../../p_work/gcc/fortran/parse.c:3758 #11 0x0000000100068708 in parse_contained (module=1) at ../../p_work/gcc/fortran/parse.c:3698 #12 0x0000000100069c8a in gfc_parse_file () at ../../p_work/gcc/fortran/parse.c:3953 #13 0x00000001000a291c in gfc_be_parse_file (set_yydebug=<value temporarily unavailable, due to optimizations>) at ../../p_work/gcc/fortran/f95-lang.c:239 #14 0x00000001006d6b5a in toplev_main (argc=2, argv=0x7fff5fbfd9e8) at ../../p_work/gcc/toplev.c:1053 #15 0x00000001000019e4 in start () Although gfortran should not give an ICE, I have doubts about the validity of the code.
(In reply to comment #3) > Reduced test: [...] (In reply to comment #4) > Further reduced test that does not give an ICE, but several errors: > Although gfortran should not give an ICE, I have doubts about the validity of > the code. Well, using type omega_procedures procedure(number_particles_out), nopass, pointer :: number_particles_out => NULL() end type omega_procedures is definitely wrong: You tell that the procedure pointer has the interface of itself. By itself, gfortran also properly diagnoses this: Error: Interface 'number_particles_out' of procedure pointer component 'number_particles_out' at (1) must be explicit But seemingly, this resolution comes too late - the ICE happens earlier. That's definitely an ICE-on-invalid-code bug. * * * However, if I compile the real, 7479 line program with ifort, I do not get any error message. I try now to reduce - using delta - the big program, under the constraint that it still compiles without any error with ifort. Let's see where that leads to. Cf. http://gcc.gnu.org/wiki/A_guide_to_testcase_reduction
(In reply to comment #5) > Well, using > type omega_procedures > procedure(number_particles_out), nopass, pointer :: number_particles_out > => NULL() > end type omega_procedures > > is definitely wrong: You tell that the procedure pointer has the interface of > itself. But that's not the problem: module m implicit none type t procedure(p1_type), nopass, pointer :: p1 => NULL() procedure(p2_type), nopass, pointer :: p2 => NULL() end type t contains subroutine proc (t1, t2) type(t), intent(in) :: t1, t2 integer, dimension(t1%p1(), t2%p2()) :: table end subroutine proc end module m produces the same error. What is invaild about the code is that t1%p1() and t2%p2() are not initialization expressions. Everthing works fine, when the tables are allocatable. BTW: gfortran produces correct code for the variant when the procedures are not procedure pointers. I stumpled over this OCE when rewriting some code.
(In reply to comment #6) > What is invaild about the code is that t1%p1() and t2%p2() are not > initialization expressions. Everthing works fine, when the tables are > allocatable. That was the origin of my question about the validity of the code. > BTW: gfortran produces correct code for the variant when the procedures are not > procedure pointers. I stumpled over this OCE when rewriting some code. Why would this make the code valid?
(In reply to comment #6) > But that's not the problem: > type t > procedure(p1_type), nopass, pointer :: p1 => NULL() > procedure(p2_type), nopass, pointer :: p2 => NULL() That's not valid either as you have not defined "p1_type" - replacing it by INTEGER should work, though. -- Well, it actually does not as specification expressions need to be PURE. * * * Daniel, Janus: What do you think about the following incomplete patch? It needs some extra handling as, e.g., the PURE check fails for the procedure pointer (it works for the type-bound procedure) and maybe one should insert an assert that it is really a function and not a subroutine and things like that, but otherwise it seems to work. Test case: !---------------------------- module m implicit none type t procedure(p1_type), nopass, pointer :: p1 => NULL() contains procedure, nopass :: tbp => p1_type end type t contains subroutine proc (t1, t2) type(t), intent(in) :: t1, t2 integer, dimension(t1%p1(), t2%tbp()) :: table end subroutine proc pure function p1_type() integer :: p1_type p1_type = 42 end function p1_type end module m !---------------------------- Index: expr.c =================================================================== --- expr.c (revision 157899) +++ expr.c (working copy) @@ -3559,6 +3559,8 @@ gfc_traverse_expr (gfc_expr *expr, gfc_s switch (expr->expr_type) { + case EXPR_PPC: + case EXPR_COMPCALL: case EXPR_FUNCTION: for (args = expr->value.function.actual; args; args = args->next) {
(In reply to comment #7) > (In reply to comment #6) > > What is invaild about the code is that t1%p1() and t2%p2() are not > > initialization expressions. Everthing works fine, when the tables are > > allocatable. > > That was the origin of my question about the validity of the code. What you have is called an "automatic (explicit) array", which does not need to have initialization expressions for bounds but just specification expressions: 5.3.8.2 Explicit-shape array R516 explicit-shape-spec is [ lower-bound : ] upper-bound R517 lower-bound is specification-expr R518 upper-bound is specification-expr C531 (R516) An explicit-shape-spec whose bounds are not constant expressions shall appear only in a subprogram, derived type denition, BLOCK construct, or interface body. 7.1.11 Specification expression [...] A function is a specification function if it is a pure function, is not a standard intrinsic function, is not an internal function, is not a statement function, and does not have a dummy procedure argument.
(In reply to comment #8) > That's not valid either as you have not defined "p1_type" - replacing it by > INTEGER should work, though. -- Well, it actually does not as specification > expressions need to be PURE. Doesn't help module m implicit none type t procedure(p1_type), nopass, pointer :: p1 => NULL() procedure(p2_type), nopass, pointer :: p2 => NULL() end type t abstract interface pure function p1_type () result (n) integer :: n end function p1_type pure function p2_type () result (n) integer :: n end function p2_type end interface contains subroutine proc (t1, t2) type(t), intent(in) :: t1, t2 integer, dimension(t1%p1(), t2%p2()) :: table end subroutine proc end module m (The abstract interface is in the original bug report, but was removed in Dominiques's reduction).
The patch in comment #8 fixes the ICEs for the various reduced tests, however for the original code I get ward.f90:405.19: end module ward_lib 1 Internal Error at (1): gfc_is_constant_expr(): Unknown expression type
(In reply to comment #11) > Internal Error at (1): > gfc_is_constant_expr(): Unknown expression type Try the following patch; however, as written in comment 8 the PURE attribute is lost somewhere thus the patch is not sufficient. Index: gcc/fortran/expr.c =================================================================== --- gcc/fortran/expr.c (Revision 158016) +++ gcc/fortran/expr.c @@ -782,6 +782,8 @@ gfc_is_constant_expr (gfc_expr *e) break; case EXPR_FUNCTION: + case EXPR_PPC: + case EXPR_COMPCALL: /* Specification functions are constant. */ if (check_specification_function (e) == MATCH_YES) { @@ -3560,6 +3562,8 @@ gfc_traverse_expr (gfc_expr *expr, gfc_s switch (expr->expr_type) { + case EXPR_PPC: + case EXPR_COMPCALL: case EXPR_FUNCTION: for (args = expr->value.function.actual; args; args = args->next) {
I somehow miss the setting of expr->value.function.esym and thus expr->value.function.esym->attr for PPC in resolve.c (e.g. in resolve_expr_ppc). Contrary to resolve_compcall, where on has: e->value.function.esym = target->n.sym; (Setting it is not trivial as esym is gfc_symbol while the PPC is a component.) Clearly, e->value.function.esym != NULL as otherwise one would never reach the PURE check in expr.c's external_spec_function but segfault: f = e->value.function.esym; if (!f->attr.pure && !f->attr.elemental) In any case, e->value.function.esym->attr does not seem to be correctly set.
Looked at the wrong check. The following (lightly tested) should work: Index: gcc/fortran/expr.c =================================================================== --- gcc/fortran/expr.c (revision 158042) +++ gcc/fortran/expr.c (working copy) @@ -782,6 +782,8 @@ gfc_is_constant_expr (gfc_expr *e) break; case EXPR_FUNCTION: + case EXPR_PPC: + case EXPR_COMPCALL: /* Specification functions are constant. */ if (check_specification_function (e) == MATCH_YES) { @@ -2808,6 +2810,7 @@ check_restricted (gfc_expr *e) gfc_try gfc_specification_expr (gfc_expr *e) { + gfc_component *comp; if (e == NULL) return SUCCESS; @@ -2822,7 +2825,9 @@ gfc_specification_expr (gfc_expr *e) if (e->expr_type == EXPR_FUNCTION && !e->value.function.isym && !e->value.function.esym - && !gfc_pure (e->symtree->n.sym)) + && !gfc_pure (e->symtree->n.sym) + && (!gfc_is_proc_ptr_comp (e, &comp) + || !comp-> attr.pure)) { gfc_error ("Function '%s' at %L must be PURE", e->symtree->n.sym->name, &e->where); @@ -3560,6 +3565,8 @@ gfc_traverse_expr (gfc_expr *expr, gfc_s switch (expr->expr_type) { + case EXPR_PPC: + case EXPR_COMPCALL: case EXPR_FUNCTION: for (args = expr->value.function.actual; args; args = args->next) {
With the patch in comment #14, the test in comment #1 compiles and gives: evt= 234, flv= 1, col= 2, hel= 3, -0.122E-13 + i* 0.675E-14 ~ 0.267E-02 evt= 234, flv= 1, col= 2, hel= 6, -0.122E-13 + i*-0.675E-14 ~ 0.267E-02 evt= 289, flv= 1, col= 2, hel= 3, -0.161E-12 + i* 0.292E-12 ~ 0.446E-01 evt= 289, flv= 1, col= 2, hel= 6, -0.161E-12 + i*-0.292E-12 ~ 0.446E-01 evt= 380, flv= 1, col= 2, hel= 3, 0.102E-11 + i*-0.568E-13 ~ 0.817E-01 evt= 380, flv= 1, col= 2, hel= 4, -0.383E-12 + i* 0.213E-13 ~ 0.817E-01 evt= 380, flv= 1, col= 2, hel= 5, -0.383E-12 + i*-0.213E-13 ~ 0.817E-01 evt= 380, flv= 1, col= 2, hel= 6, 0.102E-11 + i* 0.568E-13 ~ 0.817E-01 evt= 380, flv= 1, col= 5, hel= 3, -0.108E-11 + i* 0.710E-12 ~ 0.217E+00 evt= 380, flv= 1, col= 5, hel= 6, -0.108E-11 + i*-0.710E-12 ~ 0.217E+00 10 failures in 40000 attempts STOP 1 Regtested without failure.
Subject: Bug 43591 Author: burnus Date: Sat Apr 10 14:24:46 2010 New Revision: 158191 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=158191 Log: 2010-04-10 Tobias Burnus <burnus@net-b.de> PR fortran/43591 * expr.c (gfc_is_constant_expr, gfc_traverse_expr): Handle proc-pointers and type-bound procedures. (gfc_specification_expr): Check proc-pointers for pureness. 2010-04-10 Tobias Burnus <burnus@net-b.de> PR fortran/43591 * gfortran.dg/spec_expr_6.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/spec_expr_6.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/expr.c trunk/gcc/testsuite/ChangeLog
Fixed on the trunk (4.6). Planned to be committed also to GCC 4.5.1. Patch: http://gcc.gnu.org/ml/fortran/2010-04/msg00093.html Thanks for the bug report!
(In reply to comment #17) > Fixed on the trunk (4.6). Planned to be committed also to GCC 4.5.1. Patch was applied to trunk about 6 weeks ago - how are the backporting plans?
Subject: Bug 43591 Author: burnus Date: Wed May 19 07:22:00 2010 New Revision: 159556 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=159556 Log: 2010-05-19 Tobias Burnus <burnus@net-b.de> PR fortran/43591 * expr.c (gfc_is_constant_expr, gfc_traverse_expr): Handle proc-pointers and type-bound procedures. (gfc_specification_expr): Check proc-pointers for pureness. 2010-05-19 Tobias Burnus <burnus@net-b.de> PR fortran/43591 * gfortran.dg/spec_expr_6.f90: New test. Added: branches/gcc-4_5-branch/gcc/testsuite/gfortran.dg/spec_expr_6.f90 Modified: branches/gcc-4_5-branch/gcc/fortran/ChangeLog branches/gcc-4_5-branch/gcc/fortran/expr.c branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
(In reply to comment #18) > Patch was applied to trunk about 6 weeks ago - how are the backporting plans? Thanks for the reminder! Thorsten: Thanks for the bug report. As I do not intent to backport it to 4.4.x: Close as FIXED.