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

Reply via email to