Bug 59023 - [4.9 regression] ICE in gfc_search_interface with BIND(C)
Summary: [4.9 regression] ICE in gfc_search_interface with BIND(C)
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.9.0
: P4 normal
Target Milestone: 4.9.0
Assignee: janus
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: 29383
  Show dependency treegraph
 
Reported: 2013-11-06 14:19 UTC by Francois-Xavier Coudert
Modified: 2014-01-06 11:33 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-11-17 00:00:00


Attachments
patch (1.66 KB, patch)
2013-12-30 19:41 UTC, janus
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Francois-Xavier Coudert 2013-11-06 14:19:51 UTC
The code below triggers an ICE on current trunk (on x86_64-apple-darwin13, but I don't suppose it matters much). It works with gfortran 4.8.0 and 4.8.2, as well as all other versions since 4.3 at least.

!!!!!!!!!!!!!!!!!!!!!
module foo
  type t
    integer hidden
  end type
contains
  subroutine bar
    type(t) :: toto
    interface
      integer function helper() bind(c)
      end function
    end interface
    toto = t(helper())
  end subroutine
end module
!!!!!!!!!!!!!!!!!!!!!


It is somewhat frustrating, because this bug is triggered in my current (tentative) implementation of IEEE_ARITHMETIC's IEEE_CLASS routine.
Comment 1 Francois-Xavier Coudert 2013-11-06 21:39:44 UTC
Using an intermediate variable works around the bug. If you replace:

toto = t(helper())

with

i = helper()
toto = t(i)

where i is an integer variable, you don't have the ICE anymore.
Comment 2 Dominique d'Humieres 2013-11-17 13:45:43 UTC
Backtrace

Program received signal SIGSEGV, Segmentation fault.
0x000000010003da12 in gfc_search_interface (intr=0x141d08f00, sub_flag=0, ap=0x141d1e0a0) at ../../work/gcc/fortran/interface.c:3407
3407	    if (a->expr && a->expr->expr_type == EXPR_NULL
(gdb) bt
#0  0x000000010003da12 in gfc_search_interface (intr=0x141d08f00, sub_flag=0, ap=0x141d1e0a0) at ../../work/gcc/fortran/interface.c:3407
#1  0x0000000100085611 in gfc_resolve_expr (e=0x141d08f00) at ../../work/gcc/fortran/resolve.c:2477
#2  0x000000010008a2f0 in resolve_code (code=<optimized out>, ns=<optimized out>) at ../../work/gcc/fortran/resolve.c:9772
#3  0x000000010008cac4 in resolve_codes (ns=0x141d08f00) at ../../work/gcc/fortran/resolve.c:14624
#4  0x000000010008c9c8 in resolve_codes (ns=0x141d08f00) at ../../work/gcc/fortran/resolve.c:14610
#5  0x000000010008cbbd in gfc_resolve (ns=<optimized out>) at ../../work/gcc/fortran/resolve.c:14652
#6  0x00000001000786e1 in gfc_parse_file () at ../../work/gcc/fortran/parse.c:4672
#7  0x00000001000b9d96 in gfc_be_parse_file () at ../../work/gcc/fortran/f95-lang.c:188
#8  0x000000010082f774 in compile_file () at ../../work/gcc/toplev.c:545
#9  0x000000010083190a in toplev_main (argc=1, argv=0x7fff5fbff550) at ../../work/gcc/toplev.c:1891
(gdb) p *intr
$1 = {sym = 0x141d1d210, where = {nextc = 0x141d0d3c0, lb = 0x141d0d380}, next = 0x0warning: (Internal error: pc 0x0 in read in psymtab, but not in symtab.)

}
Comment 3 Dominique d'Humieres 2013-12-26 13:21:32 UTC
The ICE appeared between r199034 (2013-05-17, no ICE) and r199221 (2013-05-22, ICE).
Comment 4 Thomas Koenig 2013-12-26 15:10:38 UTC
Valgrind backtrace:


==19413== Memcheck, a memory error detector
==19413== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==19413== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==19413== Command: /home/ig25/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/f951 foo.f90
==19413== 
==19413== Invalid read of size 4
==19413==    at 0x57708A: gfc_search_interface(gfc_interface*, int, gfc_actual_arglist**) (interface.c:3439)
==19413==    by 0x5BD333: gfc_resolve_expr(gfc_expr*) (resolve.c:2480)
==19413==    by 0x5C1C03: resolve_code(gfc_code*, gfc_namespace*) (resolve.c:9775)
==19413==    by 0x5C4BBE: resolve_codes(gfc_namespace*) (resolve.c:14566)
==19413==    by 0x5C4AC7: resolve_codes(gfc_namespace*) (resolve.c:14552)
==19413==    by 0x5C4CA2: gfc_resolve(gfc_namespace*) [clone .part.45] (resolve.c:14594)
==19413==    by 0x5B0BEF: gfc_parse_file() (parse.c:4672)
==19413==    by 0x5EE8C5: gfc_be_parse_file() (f95-lang.c:188)
==19413==    by 0x9F9E55: compile_file() (toplev.c:547)
==19413==    by 0x9FBE27: toplev_main(int, char**) (toplev.c:1887)
==19413==    by 0x5A54BE4: (below main) (in /lib64/libc-2.18.so)
==19413==  Address 0x8b4853fd89495554 is not stack'd, malloc'd or (recently) free'd
==19413==
Comment 5 janus 2013-12-30 17:45:30 UTC
(In reply to Dominique d'Humieres from comment #3)
> The ICE appeared between r199034 (2013-05-17, no ICE) and r199221
> (2013-05-22, ICE).

In this range are three committs for PR 48858, which might be to blame here: r199118, r199119, r199120. At first sight I suspect the middle one could be the culprit ...
Comment 6 janus 2013-12-30 18:05:34 UTC
(In reply to janus from comment #5)
> In this range are three committs for PR 48858, which might be to blame here:
> r199118, r199119, r199120. At first sight I suspect the middle one could be
> the culprit ...

Actually the last one seem to be responsible instead. In particular reverting the resolve.c parts of r199120 makes the ICE go away.
Comment 7 janus 2013-12-30 19:41:59 UTC
Created attachment 31542 [details]
patch

Here is a patch which removes the ICE, although I don't actually understand why (maybe someone else can see this). It corresponds to a partial reversion of r199120, namely the changes to 'gfc_verify_binding_labels'. It is the smallest subset of the above commit that I was able to find that removes the ICE. It regresses at least on some of the binding_label_tests_* in the testsuite.
Comment 8 janus 2013-12-30 20:00:38 UTC
I had a closer look at what actually changes with the patch in comment 7, and found out that the crucial part is that the patch does not set the 'ns' member of the gsymbol. This observation leads to a much simpler patch to fix the ICE:


Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 206249)
+++ gcc/fortran/resolve.c	(working copy)
@@ -10164,7 +10164,6 @@ gfc_verify_binding_labels (gfc_symbol *sym)
       gsym->sym_name = sym->name;
       gsym->binding_label = sym->binding_label;
       gsym->binding_label = sym->binding_label;
-      gsym->ns = sym->ns;
       gsym->mod_name = module;
       if (sym->attr.function)
         gsym->type = GSYM_FUNCTION;


Unfortunately I still don't really understand *why* this fixes the ICE. Moreover, it still fails on some binding_label_tests_*.

(Btw, also one of the duplicate lines, which set the binding_label, should be removed.)
Comment 9 janus 2013-12-30 21:32:04 UTC
The following patch is more reasonable, I think:


Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 206252)
+++ gcc/fortran/resolve.c	(working copy)
@@ -2360,7 +2360,7 @@ resolve_global_procedure (gfc_symbol *sym, locus *
       gfc_symbol *def_sym;
 
       /* Resolve the gsymbol namespace if needed.  */
-      if (!gsym->ns->resolved)
+      if (!gsym->ns->resolved && !gsym->binding_label)
 	{
 	  gfc_dt_list *old_dt_list;
 	  struct gfc_omp_saved_state old_omp_state;


However, it regresses on value_tests_f03.f90.
Comment 10 janus 2013-12-31 00:03:13 UTC
Here is a variant which regtests cleanly:


Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 206252)
+++ gcc/fortran/resolve.c	(working copy)
@@ -2351,6 +2351,7 @@ resolve_global_procedure (gfc_symbol *sym, locus *
   if ((sym->attr.if_source == IFSRC_UNKNOWN
        || sym->attr.if_source == IFSRC_IFBODY)
       && gsym->type != GSYM_UNKNOWN
+      && !gsym->binding_label
       && gsym->ns
       && gsym->ns->resolved != -1
       && gsym->ns->proc_name
Comment 11 janus 2014-01-06 11:31:37 UTC
Author: janus
Date: Mon Jan  6 11:31:34 2014
New Revision: 206355

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

	PR fortran/59023
	PR fortran/59662
	* resolve.c (resolve_global_procedure): Don't apply to c-binding
	procedures.
	(gfc_verify_binding_labels): Remove duplicate line.

2014-01-06  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/59023
	* gfortran.dg/bind_c_procs_2.f90: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/bind_c_procs_2.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/testsuite/ChangeLog
Comment 12 janus 2014-01-06 11:33:42 UTC
Fixed with r206355. Closing.