On 06/26/2014 06:25 AM, Chen Gang wrote: > > BTW: one linux kernel member found a gcc issue for the latest version > (4.10.0 20140622 or later), but for old version (e.g. 4.10.0 2014060*), > it is OK. It is my chance to fix it (hope can finish within 2014-06-30). >
For this issue, at present, I find root cause: when find duplicate decls, it need merge with the old one, and let old and new share 'function_decl.f', After free new, also free the old. I shall continue analysing this issue, and welcome any members' suggestions or completions. The related git number is 71e19e54060804493e13748613077b0e69c0cfd9, and the related contents are below: diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 54d0de7..47cf3cc 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2014-06-07 Jan Hubicka <hubi...@ucw.cz> + + * c-decl.c (merge_decls): Use set_decl_section_name. + (duplicate_decls): Remove node if it exists. + 2014-06-05 S. Gilles <sgil...@terpmail.umd.edu> PR c/53119 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 8fb3296..524b064 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -2304,8 +2304,10 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) We want to issue an error if the sections conflict but that must be done later in decl_attributes since we are called before attributes are assigned. */ - if (DECL_SECTION_NAME (newdecl) == NULL_TREE) - DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl); + if ((DECL_EXTERNAL (olddecl) || TREE_PUBLIC (olddecl) || TREE_STATIC (olddecl)) + && DECL_SECTION_NAME (newdecl) == NULL_TREE + && DECL_SECTION_NAME (olddecl)) + set_decl_section_name (newdecl, DECL_SECTION_NAME (olddecl)); /* Copy the assembler name. Currently, it can only be defined in the prototype. */ @@ -2574,6 +2576,13 @@ duplicate_decls (tree newdecl, tree olddecl) merge_decls (newdecl, olddecl, newtype, oldtype); /* The NEWDECL will no longer be needed. */ + if (TREE_CODE (newdecl) == FUNCTION_DECL + || TREE_CODE (newdecl) == VAR_DECL) + { + struct symtab_node *snode = symtab_get_node (newdecl); + if (snode) + symtab_remove_node (snode); + } [...] The related operation: root@gchen:/upstream/linux# cat elevator.i extern int __attribute__ ((__section__(".init.text"))) elv_register(void) { return 0; } extern typeof(elv_register) elv_register; root@gchen:/upstream/linux# /usr/local/libexec/gcc/score-elf/4.10.0/cc1 elevator.i elv_register Analyzing compilation unit Segmentation fault (core dumped) root@gchen:/upstream/linux# /usr/local/bin/score-elf-gcc -v Using built-in specs. COLLECT_GCC=/usr/local/bin/score-elf-gcc COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/score-elf/4.10.0/lto-wrapper Target: score-elf Configured with: ../gcc/configure --without-header --disable-nls --enable-language=c --disable-threads --disable-shared --enable-werror=no target_configargs=enable_vtable_verify=yes --target=score-elf --enable-obsolete : (reconfigured) ../gcc/configure --without-header --disable-nls --enable-language=c --disable-threads --disable-shared --enable-werror=no target_configargs=enable_vtable_verify=yes --target=score-elf --enable-obsolete --enable-debug --disable-release Thread model: single gcc version 4.10.0 20140625 (experimental) (GCC) Thanks. -- Chen Gang Open, share, and attitude like air, water, and life which God blessed