NEWDECL dereferences shared data of OLDDECL, or when free NEWDECL, also have effect with OLDDECL. At present, only fix the related reference for current issue. If find another related issue, can follow this fix.
The related git number is 71e19e54060804493e13748613077b0e69c0cfd9, and the related information: 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) After this patch, can let Linux kernel pass defconfig under score. Signed-off-by: Chen Gang <gang.chen.5...@gmail.com> --- gcc/ChangeLog | 5 +++++ gcc/c/c-decl.c | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 34e7c93..241a7b7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2014-06-29 Chen Gang <gang.chen.5...@gmail.com> + + * c/c-decl.cl (merge_decls): NEWDECL dereferences shared data of + OLDDECL, or when free NEWDECL, also have effect with OLDDECL. + 2014-06-28 Jan Hubicka <hubi...@ucw.cz> * tree-streamer-out.c (pack_ts_type_common_value_fields): Stream if type diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index def10a2..373e5fb 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -2552,6 +2552,17 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) || (TREE_CODE (olddecl) == VAR_DECL && TREE_STATIC (olddecl)))) make_decl_rtl (olddecl); + + /* NEWDECL dereferences shared data of OLDDECL, or after free NEWDECL, + also have effect with OLDDECL */ + if (TREE_CODE (newdecl) == FUNCTION_DECL) + { + DECL_FUNCTION_SPECIFIC_TARGET (newdecl) = NULL; + DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl) = NULL; + DECL_STRUCT_FUNCTION (newdecl) = NULL; + DECL_RESULT (newdecl) = NULL; + DECL_INITIAL (newdecl) = NULL; + } } /* Handle when a new declaration NEWDECL has the same name as an old -- 1.7.11.7