Bug 36463

Summary: gfc_get_default_type(): Bad symbol
Product: gcc Reporter: Dominique d'Humieres <dominiq>
Component: fortranAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: burnus, d, fxcoudert, gcc-bugs, janus
Priority: P4 Keywords: ice-on-valid-code
Version: 4.4.0   
Target Milestone: 4.4.0   
Host: i686-apple-darwin9 Target: i686-apple-darwin9
Build: i686-apple-darwin9 Known to work:
Known to fail: Last reconfirmed: 2008-10-20 08:09:43

Description Dominique d'Humieres 2008-06-08 09:54:33 UTC
On i686-apple-darwin9 with revision 136554, I get the following ICEs on the codes from pr35971 and the two codes from 

http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/ff7ae6c7a7860bca/60213205751117d4

(see pr36322):

pr35971.f90: In function 'gp':
pr35971.f90:46: internal compiler error: in expand_expr_real_1, at expr.c:7264

This ICEs replace the errors:

pr35971.f90:46.25:

         gp = get_funloc(make_mess,aux)
                        1
Error: Type/rank mismatch in argument 'x' at (1)
pr35971.f90:82.16:

   use other_fun
               1
Fatal Error: Can't open module file 'other_fun.mod' for reading at (1): No such file or directory
Comment 1 Dominique d'Humieres 2008-06-08 12:01:54 UTC
The code in comment #1 of PR35971 compiles without error.

Comment 2 Dominique d'Humieres 2008-06-09 09:07:53 UTC
reduced test case:

module other_fun
   use ISO_C_BINDING
   implicit none
   private
! Message to be returned by procedure pointed to
! by the C_FUNPTR
   character, allocatable, save :: my_message(:)
! Interface block for the procedure pointed to
! by the C_FUNPTR
   public abstract_fun
   abstract interface
      function abstract_fun(x)
         use ISO_C_BINDING
         import my_message
         implicit none
         integer(C_INT) x(:)
         character(size(my_message),C_CHAR) abstract_fun(size(x))
      end function abstract_fun
   end interface
   contains
! Procedure to store the message and get the C_FUNPTR
      function gp(message) bind(C,name='BlAh')
!         procedure(abstract_fun) make_mess
         character(kind=C_CHAR) message(*)
         type(C_FUNPTR) gp
         integer(C_INT64_T) i

         i = 1
         do while(message(i) /= C_NULL_CHAR)
            i = i+1
         end do
         my_message = message(int(1,kind(i)):i-1)
         gp = get_funloc(make_mess,aux)
!         gp = aux(make_mess)
      end function gp

! Intermediate procedure to pass the function and get
! back the C_FUNPTR
      function get_funloc(x,y)
         procedure(abstract_fun) x
         type(C_FUNPTR) y
         external y
         type(C_FUNPTR) get_funloc

         get_funloc = y(x)
      end function get_funloc

! Procedure to convert the function to C_FUNPTR
      function aux(x)
         interface
            subroutine x() bind(C)
            end subroutine x
         end interface
         type(C_FUNPTR) aux

         aux = C_FUNLOC(x)
      end function aux

! Procedure pointed to by the C_FUNPTR
      function make_mess(x)
         integer(C_INT) x(:)
         character(size(my_message),C_CHAR) make_mess(size(x))

         make_mess = transfer(my_message,make_mess(1))
      end function make_mess
end module other_fun

Comment 3 Dominique d'Humieres 2008-06-09 09:09:15 UTC
Withe following patch the ICE is changed to 

pr35971_red.f90:33.25:

         gp = get_funloc(make_mess,aux)
                        1
Error: Type/rank mismatch in argument 'x' at (1)

--- /opt/gcc/_gcc_clean/gcc/fortran/resolve.c   2008-06-08 11:16:33.000000000 +0200
+++ /opt/gcc/gcc-4.4-work/gcc/fortran/resolve.c 2008-06-09 10:57:13.000000000 +0200
@@ -7912,7 +7912,7 @@
          sym->attr.dimension = ifc->attr.dimension;
          sym->attr.recursive = ifc->attr.recursive;
          sym->attr.always_explicit = ifc->attr.always_explicit;
-         sym->as = gfc_copy_array_spec (ifc->as);
+         /* sym->as = gfc_copy_array_spec (ifc->as); */
          copy_formal_args (sym, ifc);
        }
       else if (sym->ts.interface->name[0] != '\0')

Comment 4 Tobias Burnus 2008-07-27 17:13:16 UTC
> Withe following patch the ICE is changed to 
> pr35971_red.f90:33.25:
>          gp = get_funloc(make_mess,aux)
>                         1
> Error: Type/rank mismatch in argument 'x' at (1)
> -         sym->as = gfc_copy_array_spec (ifc->as);
> +         /* sym->as = gfc_copy_array_spec (ifc->as); */

The patch is wrong. Before there were two bugs - the one fixed by the adding the sym->as line and the wrong memory access. Fixing the first bug, which solved one program (see test suite), now reveals the next problem.

I think that was already tracked in one of the bind(C) PRs. Unfortunately, there are now so many that I lost track. In any case is PR 36322 about the same c.l.f. test case.
Comment 5 Tobias Burnus 2008-07-27 17:19:48 UTC
Regarding the test case in comment 2, ifort complains:

fjf.f90(14): error #6487: Local array names may not be used as IMPORT-name_entities   [MY_MESSAGE]
         import my_message
----------------^

(my_message is a module-global variable)
Comment 6 janus 2008-10-20 08:09:43 UTC
Actually I don't understand this ifort error message. I had a look in the standard, but couldn't find anything which would render the IMPORT statement invalid.
Comment 7 Dominique d'Humieres 2008-10-20 08:56:59 UTC
With ifort (IFORT) 10.1 20070913, I get:

fortcom: Error: pr35971_red.f90, line 11: Syntax error, found IDENTIFIER 'INTERFACE' when expecting one of: => = . ( : %
   abstract interface
------------^
fortcom: Error: pr35971_red.f90, line 14: This statement is permitted only in an INTERFACE block
         import my_message
---------^
fortcom: Error: pr35971_red.f90, line 11: This statement must not appear in the specification part of a module
   abstract interface
---^
fortcom: Error: pr35971_red.f90, line 11: A specification statement cannot appear in the executable section.
   abstract interface
------------^
... a lot of errors.
Comment 8 janus 2008-10-20 09:19:21 UTC
I think ifort 10.1 does neither support ABSTRACT interfaces, nor PROCEDURE statements (therefore it cannot compile this test case). But there is a 11.0 beta which does support both, and which gives the error Tobias reported in comment #5.
Comment 9 janus 2008-10-20 12:02:30 UTC
*** Bug 35971 has been marked as a duplicate of this bug. ***
Comment 10 janus 2008-11-01 13:25:29 UTC
Subject: Bug 36463

Author: janus
Date: Sat Nov  1 13:24:03 2008
New Revision: 141515

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141515
Log:
2008-11-01  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/36322
	PR fortran/36463
	* gfortran.h: New function gfc_expr_replace_symbols.
	* decl.c (match_procedure_decl): Increase reference count for interface.
	* expr.c: New functions replace_symbol and gfc_expr_replace_symbols.
	* resolve.c (resolve_symbol): Correctly copy array spec and char len
	of PROCEDURE declarations from their interface.
	* symbol.c (gfc_get_default_type): Enhanced error message.
	(copy_formal_args): Call copy_formal_args recursively for arguments.
	* trans-expr.c (gfc_conv_function_call): Bugfix.


2008-11-01  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/36322
	PR fortran/36463
	* gfortran.dg/proc_decl_17.f90: New.
	* gfortran.dg/proc_decl_18.f90: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/proc_decl_17.f90
    trunk/gcc/testsuite/gfortran.dg/proc_decl_18.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/decl.c
    trunk/gcc/fortran/expr.c
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/symbol.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog

Comment 11 janus 2008-11-01 13:52:31 UTC
r141515 eliminates the ICE in comment #2 and the c.l.f. example, so I guess this can not be called a regression any more. Removing the [4.4 Regression] tag.
Comment 12 janus 2008-11-01 14:06:20 UTC
To clarify the situation regarding the code on c.l.f.: The link in comment #0 points to a thread which contains two example programs. One is called "fptr" and uses Cray pointers, the other one is called "gptr" and uses procedure pointers. Both contain minor formal errors.

The "gptr" example can not be compiled with gfortran at this point, since it uses procedure pointers as function results, which are not yet supported (see PR36704).

The corrected version of the "fptr" example looks like this:


module funcs
   implicit none
! Interface block for function program fptr will invoke
! to get the C_FUNPTR
   interface
      function get_proc(mess) bind(C,name='BlAh')
         use ISO_C_BINDING
         implicit none
         character(kind=C_CHAR) mess(*)
         type(C_FUNPTR) get_proc
      end function get_proc
   end interface
end module funcs

module other_fun
   use ISO_C_BINDING
   implicit none
   private
! Message to be returned by procedure pointed to
! by the C_FUNPTR
   character, allocatable, save :: my_message(:)
! Interface block for the procedure pointed to
! by the C_FUNPTR
   public abstract_fun
   abstract interface
      function abstract_fun(x)
         use ISO_C_BINDING
         import my_message
         implicit none
         integer(C_INT) x(:)
         character(size(my_message),C_CHAR) abstract_fun(size(x))
      end function abstract_fun
   end interface
   contains
! Procedure to store the message and get the C_FUNPTR
      function gp(message) bind(C,name='BlAh')
         character(kind=C_CHAR) message(*)
         type(C_FUNPTR) gp
         integer(C_INT64_T) i

         i = 1
         do while(message(i) /= C_NULL_CHAR)
            i = i+1
         end do
         my_message = message(int(1,kind(i)):i-1)
         gp = get_funloc(make_mess,aux)
      end function gp

! Intermediate procedure to pass the function and get
! back the C_FUNPTR
      function get_funloc(x,y)
         procedure(abstract_fun) :: x
         type(C_FUNPTR) y
         external y
         type(C_FUNPTR) get_funloc

         get_funloc = y(x)
      end function get_funloc

! Procedure to convert the function to C_FUNPTR
      function aux(x)
         interface
            subroutine x() bind(C)
            end subroutine x
         end interface
         type(C_FUNPTR) aux

         aux = C_FUNLOC(x)
      end function aux

! Procedure pointed to by the C_FUNPTR
      function make_mess(x)
         integer(C_INT) x(:)
         character(size(my_message),C_CHAR) make_mess(size(x))

         make_mess = transfer(my_message,make_mess(1))
      end function make_mess
end module other_fun

program fptr
   use funcs
   use other_fun
   use ISO_C_BINDING
   implicit none
      procedure(abstract_fun) :: fun
   pointer(p,fun)
   type(C_FUNPTR) fp

   fp = get_proc('Hello, world'//achar(0))
   p = transfer(fp,p)
   write(*,'(a)') fun([1,2,3])
end program fptr


Compiling this via "gfortran-4.4 -fcray-pointer fptr.f90" yields the error:

end program fptr
               1
Internal Error at (1):
gfc_get_default_type(): Bad symbol '@3'


With 4.3 I get an ICE on this, so it is no regression, though I haven't tried 4.2 or earlier.
Comment 13 janus 2008-11-01 14:20:44 UTC
Here is a maximally reduced (and slightly modified) version of comment #12, which gives the same error:


module other_fun
   abstract interface
      function abstract_fun(x)
         integer x
         integer abstract_fun(x)
      end function abstract_fun
   end interface
end module other_fun

program fptr
   use other_fun
   procedure(abstract_fun) :: fun
end program fptr


"gfortran-4.4 fptr.f90" gives the output:

end program fptr
               1
Internal Error at (1):
gfc_get_default_type(): Bad symbol '@0'

gfortran version 4.3 happily accepts this test case without complaining, so I suppose this makes it a regression again.
Comment 14 Mikael Morin 2008-11-11 15:36:33 UTC
(In reply to comment #13)
"x" is not marked as referenced, and read_cleanup makes a symtree for it with that name "@0" from gfc_get_unique_symtree. 
This behavior seems expected in some cases, maybe it is here as well, or maybe not. 
The comment at the beginning of module.c mentions "hidden symbols" for which the above applies, but I don't know what they are.
 

Comment 15 Mikael Morin 2008-11-17 22:19:23 UTC
(In reply to comment #14)
I've just discovered I was paraphrasing Janus here:
http://gcc.gnu.org/ml/fortran/2008-10/msg00219.html

The error for comment #13 was introduced the patch in comment #10.
Knowing that, I tried this:

Index: expr.c
===================================================================
--- expr.c	(révision 141942)
+++ expr.c	(copie de travail)
@@ -3514,7 +3514,7 @@ replace_symbol (gfc_expr *expr, gfc_symbol *sym, i
       && expr->symtree->n.sym->ns == sym->ts.interface->formal_ns)
     {
       gfc_symtree *stree;
-      gfc_get_sym_tree (expr->symtree->name, sym->formal_ns, &stree);
+      gfc_get_sym_tree (expr->symtree->n.sym->name, sym->formal_ns, &stree);
       stree->n.sym->attr = expr->symtree->n.sym->attr;
       expr->symtree = stree;
     }

I don't know if it is solving the right problem, but at least the testcase in comment #13 compiles with it. 
Comment 16 janus 2008-11-17 22:56:28 UTC
> I don't know if it is solving the right problem, but at least the testcase in
> comment #13 compiles with it. 

This indeed fixes it. Nice job. Obviously I was looking for the solution in the wrong places.

Btw it also makes comment #12 compile, while the resulting executable produces a segfault. But I guess this is due to the weird things which this program does(?).

Thanks for finding this.
Comment 17 Mikael Morin 2008-11-18 13:23:06 UTC
(In reply to comment #16)
> Btw it also makes comment #12 compile, while the resulting executable produces
> a segfault. But I guess this is due to the weird things which this program
> does(?).
Not really. 
The problems comes from the assignment to my_message, which is allocatable and should be (implicitly) reallocated. This is PR35810.
Allocating my_message separately fixes the segfault, but I still get a valgrind error. :-(
Comment 18 Mikael Morin 2008-11-25 13:28:54 UTC
Subject: Bug 36463

Author: mikael
Date: Tue Nov 25 13:27:26 2008
New Revision: 142191

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

	PR fortran/36463
	* expr.c (replace_symbol): Don't replace the symtree
	if the expresion is an intrinsic function. Don't create
	non-existent symtrees.  Use symbol's name instead of symtree's,
	different in case of module procedure dummy arguments.

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

	PR fortran/36463
	* gfortran.dg/proc_decl_20.f90: New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/proc_decl_20.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/expr.c
    trunk/gcc/testsuite/ChangeLog

Comment 19 janus 2008-11-28 11:54:15 UTC
Since comment #13 is fixed, this should not be labeled a regression any more I guess. Are there still problems with comment #12 (apart from PR35810), or can we close this PR?
Comment 20 Tobias Burnus 2008-11-28 12:52:21 UTC
(In reply to comment #19)
> Since comment #13 is fixed, this should not be labeled a regression any more I
> guess. Are there still problems with comment #12 (apart from PR35810), or can
> we close this PR?

I think only PR 35971, comment 0 (with modification of PR 35971 comment 2) and [essentially/exactly the same] comment 12 of this PR remain (= compiles, but ICE at run time).

I don't see ad hoc whether PR 35810 is the problem; if you close this PR, can you add a note to the PR that one should re-check PR 35971, comment 0 and PR 36463, comment 12 before closing? That way we are sure that the test case does not get lost, if PR 35810 does not fix the remaining issues.
Comment 21 Mikael Morin 2008-11-28 13:24:28 UTC
(In reply to comment #20)
> I don't see ad hoc whether PR 35810 is the problem; 
With this I get no ICE, and no valgrind error either. :-)

--- pr36463_12.f90	2008-11-28 15:03:07.000000000 +0100
+++ pr36463_12_works.f90	2008-11-28 15:02:15.000000000 +0100
@@ -42,6 +42,7 @@
          do while(message(i) /= C_NULL_CHAR)
             i = i+1
          end do
+         allocate(my_message(i-1))
          my_message = message(int(1,kind(i)):i-1)
          gp = get_funloc(make_mess,aux)
       end function gp


> if you close this PR, can
> you add a note to the PR that one should re-check PR 35971, comment 0 and PR
> 36463, comment 12 before closing? That way we are sure that the test case does
> not get lost, if PR 35810 does not fix the remaining issues.
> 
I will do that. 
We could as well add James' gptr as a test case for a procedure pointer PR (there is probably one?). Then, I agree we can close this PR.

Comment 22 janus 2008-11-28 13:47:56 UTC
(In reply to comment #21)
> We could as well add James' gptr as a test case for a procedure pointer PR
> (there is probably one?).

Yeah, it's PR 36704.
Comment 23 janus 2008-11-29 11:25:56 UTC
Closing.