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". ???
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.
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.
Also occurs on hppa64-hp-hpux11.11.
If we reject the common as syntactically wrong, it should never be resolved.
*** Bug 34693 has been marked as a duplicate of this bug. ***
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.
*** Bug 34698 has been marked as a duplicate of this bug. ***
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.
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.
A patch is posted at http://gcc.gnu.org/ml/gcc-patches/2008-01/msg00294.html
I still see it on x86_64-linux.
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
Fixed.
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