Bug 33375 - [4.3 Regression] ICE (segfault) gfortran.dg/common_6.f90
Summary: [4.3 Regression] ICE (segfault) gfortran.dg/common_6.f90
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P5 normal
Target Milestone: 4.3.0
Assignee: Not yet assigned to anyone
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: error-recovery, ice-on-invalid-code
: 34693 34698 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-09-10 08:36 UTC by Tobias Burnus
Modified: 2008-01-18 08:05 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-09-17 09:27:20


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2007-09-10 08:36:06 UTC
With 4.3.0 20070910 [trunk revision 128322] I get a segmentation fault when compiling gfortran.dg/common_6.f90; excerpt:

! PR 23765 : We used to incorrectly accept common blocks with no symbols
common          ! { dg-error "Syntax error" }
common y/d/     ! { dg-error "Syntax error" }

The crash happens in: resolve_common_blocks

  for (csym = common_root->n.common->head; csym; csym = csym->common_next)
    {
      if (csym->ts.type == BT_DERIVED
          && !(csym->ts.derived->attr.sequence
               || csym->ts.derived->attr.is_bind_c))

When the error happens:
(gdb) p csym->ts
$9 = {type = 0, kind = 0, derived = 0x0, cl = 0x0, is_c_interop = 6,
  is_iso_c = 1, f90_type = BT_UNKNOWN}

I don't understand why "csym->ts.derived->attr" is evaluated as "csym->ts.type != BT_DERIVED". ???
Comment 1 Tobias Burnus 2007-09-10 08:54:00 UTC
The regression occurred between (working)
  gcc version 4.3.0 20070906 (experimental) [trunk revision 128175] (GCC)
and
  gcc version 4.3.0 20070907 (experimental) [trunk revision 128228] (GCC)
on x86_64-unknown-linux-gnu.

As I cannot find any gcc/fortran/* change which could have caused this, I assign it to the middle end.
Comment 2 Tobias Burnus 2007-09-10 16:00:23 UTC
Back to fortran; I was wrong. This is not a regression, but it occurred from the beginning as valgrind shows. That it crashes is new, however.


More debugging; the line:
  common /b/x/c/  ! { dg-error "Syntax error" }
is matched properly in gfc_match_common: sym->name is "x" and the typespec looks ok as well.

However, in resolve_common_blocks:
  for (csym = common_root->n.common->head; csym; csym = csym->common_next)
    {

(gdb) p csym
$36 = (gfc_symbol *) 0xf475b0
(gdb) p sym->name
Cannot access memory at address 0x0
(gdb) p sym->ts
Cannot access memory at address 0x20

Thus something corrupts the symbol in between.
Comment 3 John David Anglin 2007-09-29 20:42:50 UTC
Also occurs on hppa64-hp-hpux11.11.
Comment 4 Tobias Schlüter 2007-10-07 20:03:21 UTC
If we reject the common as syntactically wrong, it should never be resolved.
Comment 5 Tobias Burnus 2008-01-06 21:50:15 UTC
*** Bug 34693 has been marked as a duplicate of this bug. ***
Comment 6 Tobias Burnus 2008-01-06 22:23:23 UTC
*** Bug 34693 has been marked as a duplicate of this bug. ***
Comment 7 H.J. Lu 2008-01-07 04:57:38 UTC
gfc_undo_symbols has

 for (p = changed_syms; p; p = q) 
    {    
      q = p->tlink;

      if (p->new)
        {    
          /* Symbol was new.  */
          delete_symtree (&p->ns->sym_root, p->name);

          p->refs--;
          if (p->refs < 0) 
            gfc_internal_error ("gfc_undo_symbols(): Negative refs");
          if (p->refs == 0)
            gfc_free_symbol (p);
          continue;
        }

"P" is freed. But it still accessible by resolve_common_vars somehow.
Comment 8 Tobias Burnus 2008-01-07 07:48:48 UTC
*** Bug 34698 has been marked as a duplicate of this bug. ***
Comment 9 H.J. Lu 2008-01-07 22:57:38 UTC
We are processing common block symbols which we have rejected/freed before.
This patch works for me:

Index: symbol.c
===================================================================
--- symbol.c    (revision 131352)
+++ symbol.c    (working copy)
@@ -2726,14 +2726,14 @@ gfc_commit_symbol (gfc_symbol *sym)
 /* Recursive function that deletes an entire tree and all the common
    head structures it points to.  */
 
-static void
-free_common_tree (gfc_symtree * common_tree)
+void
+gfc_free_common_tree (gfc_symtree * common_tree)
 {
   if (common_tree == NULL)
     return;
 
-  free_common_tree (common_tree->left);
-  free_common_tree (common_tree->right);
+  gfc_free_common_tree (common_tree->left);
+  gfc_free_common_tree (common_tree->right);
 
   gfc_free (common_tree);
 }  
@@ -2863,7 +2863,7 @@ gfc_free_namespace (gfc_namespace *ns)
 
   free_sym_tree (ns->sym_root);
   free_uop_tree (ns->uop_root);
-  free_common_tree (ns->common_root);
+  gfc_free_common_tree (ns->common_root);
 
   for (cl = ns->cl_list; cl; cl = cl2)
     {
Index: gfortran.h
===================================================================
--- gfortran.h  (revision 131352)
+++ gfortran.h  (working copy)
@@ -2137,6 +2137,7 @@ int gfc_symbols_could_alias (gfc_symbol 
 void gfc_undo_symbols (void);
 void gfc_commit_symbols (void);
 void gfc_commit_symbol (gfc_symbol *);
+void gfc_free_common_tree (gfc_symtree *);
 void gfc_free_namespace (gfc_namespace *);
 
 void gfc_symbol_init_2 (void);
Index: match.c
===================================================================
--- match.c     (revision 131352)
+++ match.c     (working copy)
@@ -2956,6 +2956,8 @@ done:
   return MATCH_YES;
 
 syntax:
+  gfc_free_common_tree (gfc_current_ns->common_root);
+  gfc_current_ns->common_root = NULL;
   gfc_syntax_error (ST_COMMON);
 
 cleanup:

I don't know if it is 100% correct.
Comment 10 Jerry DeLisle 2008-01-08 04:16:00 UTC
No longer segfaults on x86-64

Valgrind reports with common_6.f90

==10016== 1,160 bytes in 5 blocks are definitely lost in loss record 2 of 6
==10016==    at 0x4A059F6: malloc (vg_replace_malloc.c:149)
==10016==    by 0xB3FBD7: xmalloc (xmalloc.c:147)
==10016==    by 0x448EC4: gfc_getmem (misc.c:37)
==10016==    by 0x442281: gfc_get_common (match.c:2701)
==10016==    by 0x443F29: gfc_match_common (match.c:2793)
==10016==    by 0x452419: match_word (parse.c:64)
==10016==    by 0x45316F: decode_statement (parse.c:195)
==10016==    by 0x4535F4: next_statement (parse.c:505)
==10016==    by 0x4568E1: gfc_parse_file (parse.c:3317)
==10016==    by 0x47F414: gfc_be_parse_file (f95-lang.c:260)
==10016==    by 0x6F25E4: toplev_main (toplev.c:1042)
==10016==    by 0x3B7EC1E073: (below main) (in /lib64/libc-2.7.so)
==10016== 
==10016== LEAK SUMMARY:
==10016==    definitely lost: 1,160 bytes in 5 blocks.
Comment 11 H.J. Lu 2008-01-08 13:56:01 UTC
A patch is posted at

http://gcc.gnu.org/ml/gcc-patches/2008-01/msg00294.html
Comment 12 Richard Biener 2008-01-16 15:25:07 UTC
I still see it on x86_64-linux.
Comment 13 hjl@gcc.gnu.org 2008-01-18 01:29:57 UTC
Subject: Bug 33375

Author: hjl
Date: Fri Jan 18 01:29:11 2008
New Revision: 131621

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=131621
Log:
2008-01-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR fortran/33375
	* symbol.c (free_common_tree): Renamed to ...
	(gfc_free_common_tree): This.  Remove static.
	(gfc_free_namespace): Updated.

	* gfortran.h (gfc_free_common_tree): New.

	* match.c (gfc_match_common): Call gfc_free_common_tree () with
	gfc_current_ns->common_root and set gfc_current_ns->common_root
	to NULL on syntax error.

Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/match.c
    trunk/gcc/fortran/symbol.c

Comment 14 Uroš Bizjak 2008-01-18 08:05:14 UTC
Fixed.
Comment 15 Daniel Franke 2008-01-24 21:37:05 UTC
Subject: Bug 33375

Author: dfranke
Date: Thu Jan 24 21:36:14 2008
New Revision: 131811

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=131811
Log:
2008-01-24  Daniel Franke  <franke.daniel@gmail.com>

        PR fortran/33375
        PR fortran/34858
        * gfortran.h: Revert changes from 2008-01-17.
        * match.c: Likewise.
        * symbol.c: Likewise.
        (gfc_undo_symbols): Undo namespace changes related to common blocks.


Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/match.c
    trunk/gcc/fortran/symbol.c