On x86_64-pc-linux-gnu I get the following error when I build the latest git version of glibc: cc -nostdlib -nostartfiles -r -o /var/tmp/glibc-build/libc_pic.os \ -Wl,-d -Wl,--whole-archive /var/tmp/glibc-build/libc_pic.a -o /var/tmp/glibc-build/libc_pic.os gcc -nostdlib -nostartfiles -r -o /var/tmp/glibc-build/elf/librtld.map.o '-Wl,-(' /var/tmp/glibc-build/elf/dl-allobjs.os /var/tmp/glibc-build/libc_ pic.a -lgcc '-Wl,-)' -Wl,-Map,/var/tmp/glibc-build/elf/librtld.mapT /var/tmp/glibc-build/libc_pic.a(dl-addr.os): In function `_dl_addr_inside_object': /var/tmp/glibc/elf/dl-addr.c:155: multiple definition of `_dl_addr_inside_object' /var/tmp/glibc-build/elf/dl-allobjs.os:/var/tmp/glibc/elf/dl-open.c:673: first defined here /var/tmp/glibc-build/libc_pic.a(init-first.os):(.data+0x0): multiple definition of `__libc_multiple_libcs' /var/tmp/glibc-build/elf/dl-allobjs.os:/var/tmp/glibc/elf/rtld.c:658: first defined here collect2: error: ld returned 1 exit status make[2]: *** [/var/tmp/glibc-build/elf/librtld.map] Error 1 make[2]: *** Waiting for unfinished jobs.... I've git bisected this failure to: 3c25489e88a7ea2937c19abff9163d9f7d8ca53a is the first bad commit commit 3c25489e88a7ea2937c19abff9163d9f7d8ca53a Author: matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Tue Nov 8 16:47:16 2011 +0000 * gengtype.c (write_field_root): Avoid out-of-scope access of newv. * tree-stdarg.c (execute_optimize_stdarg): Accept clobbers. * tree.h (TREE_CLOBBER_P): New macro. * gimple.h (gimple_clobber_p): New inline function. * gimplify.c (gimplify_bind_expr): Add clobbers for all variables that go out of scope and live in memory. * tree-ssa-operands.c (get_expr_operands): Transfer volatility also for constructors. * cfgexpand.c (decl_to_stack_part): New static variable. (add_stack_var): Allocate it, and remember mapping. (fini_vars_expansion): Deallocate it. (stack_var_conflict_p): Add early outs. (visit_op, visit_conflict, add_scope_conflicts_1, add_scope_conflicts): New static functions. (expand_used_vars_for_block): Don't call add_stack_var_conflict, tidy. (expand_used_vars): Add scope conflicts. (expand_gimple_stmt_1): Expand clobbers to nothing. (expand_debug_expr): Ditto. * tree-pretty-print.c (dump_generic_node): Dump clobbers nicely. * tree-ssa-live.c (remove_unused_locals): Remove clobbers that refer to otherwise unused locals. * tree-sra.c (build_accesses_from_assign): Ignore clobbers. * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Clobbers of SSA names aren't necessary. (propagate_necessity): Accept and ignore constructors on the rhs, tidy. * gimple.c (walk_gimple_op): Accept constructors like mem_rhs. * tree-ssa-structalias.c (find_func_aliases): Clobbers don't store any known value. * tree-ssa-sccvn.c (vn_reference_lookup_3): Ditto, in particular they don't zero-initialize something. * tree-ssa-phiopt.c (cond_if_else_store_replacement_1): Ignore clobber RHS, we don't want PHI nodes with those. testsuite/ * gcc.dg/tree-ssa/20031015-1.c: Adjust. * g++.dg/tree-ssa/ehcleanup-1.C: Ditto. * g++.dg/eh/builtin1.C: Rewrite to not use local variables. * g++.dg/eh/builtin2.C: Ditto. * g++.dg/eh/builtin3.C: Ditto. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181172 138bc75d-0d04-0410-961f-82ee72b054a4
I see the same problem. Anybody else met this issue?
See http://sourceware.org/bugzilla/show_bug.cgi?id=13411 for analysis and possible patch. The newly emitted calls to _Unwind_Resume suck in new object files that weren't included before leading to these multiple defined symbols. glibc needs to deal with this in one or the other way.
I think this is a gcc bug. In particular, one of two things ought to happen: (1) Use the form of try_finally that ignores EH. This would lose clobber information on EH paths; dunno if this really turns out to be important. (2) Remove EH cleanup handlers that only involve clobbers which lead to function exit via REX. This would wait until pass_lower_eh_dispatch, as that's the first point at which we know whether we actually exit the function, post-inlining.
I agree it is a gcc bug, please see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51275 for more information.
Created attachment 26025 [details] gcc47-pr51117.patch Untested fix. This improves e.g.: struct A { char buf[64]; }; void bar (A *); void foo () { { A a; bar (&a); if (a.buf[13]) throw 1; } { A b; bar (&b); if (b.buf[13]) throw 2; } } back to 4.6 generated code quality, but it doesn't already e.g.: struct A { char buf[64]; }; void bar (A *); void foo () { A c; bar (&c); try { { A a; bar (&a); if (a.buf[13]) throw 1; else if (a.buf[52]) throw 3; } { A b; bar (&b); if (b.buf[13]) throw 2; } } catch ( ...) { throw; } } I think it should be safe to move the clobbers to the EH destination of the !stmt_can_throw_external (stmt) GIMPLE_RESX for that, but am not 100% sure about that yet and would prefer to do it incrementally anyway.
Author: jakub Date: Fri Dec 9 11:48:30 2011 New Revision: 182158 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182158 Log: PR tree-optimization/51117 * tree-eh.c (optimize_clobbers): New function. (execute_lower_eh_dispatch): Call it. Modified: trunk/gcc/ChangeLog trunk/gcc/tree-eh.c
Created attachment 26034 [details] gcc47-pr51117-sink.patch So far untested attempt to sink clobbers if a BB with all EH pred edges and a single EH succ edge, ending with internal throwing RESX contains other than that just CLOBBER stmts (and optionally debug stmts). Such BBs force us to immediately rethrow with no actual code in between, when the clobber stmts are sunk into the successor, we can actually ehcleanup those. Had to tweak a little bit the conflict detection in the expander for that though, without that it would think the vars still conflict on the incoming edge (even when no actual insns that might touch memory appear before the clobber).
Author: jakub Date: Fri Dec 9 20:50:40 2011 New Revision: 182177 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182177 Log: PR tree-optimization/51117 * tree-eh.c (optimize_clobbers): Don't remove just one clobber, but all consecutive clobbers before RESX. Use gimple_clobber_p predicate. Modified: trunk/gcc/ChangeLog trunk/gcc/tree-eh.c
Author: matz Date: Tue Dec 13 13:59:35 2011 New Revision: 182283 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182283 Log: PR tree-optimization/51117 * tree-eh.c (sink_clobbers): New function. (execute_lower_eh_dispatch): Call it for BBs ending with internally throwing RESX. * cfgexpand.c (add_scope_conflicts_1): Add all conflicts only at the first real instruction. Modified: trunk/gcc/ChangeLog trunk/gcc/cfgexpand.c trunk/gcc/tree-eh.c
Fixed.
Author: jakub Date: Thu Dec 15 17:27:08 2011 New Revision: 182379 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182379 Log: PR tree-optimization/51117 * g++.dg/opt/pr51117.C: New test. Added: trunk/gcc/testsuite/g++.dg/opt/pr51117.C Modified: trunk/gcc/testsuite/ChangeLog