http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49249
Summary: LTO streaming of builtins corrupts BLOCK lists Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: lto AssignedTo: unassig...@gcc.gnu.org ReportedBy: hubi...@gcc.gnu.org Hi, in the attached testcase (stolen from testsuite) there are two functions that use implicit declaration of abort (). Now C frontend behaves in a way that it produces two BLOCKS for each of local scopes and declares abort there: (gdb) p debug_tree (0x7ffff7692320) <block 0x7ffff7692320 used vars <function_decl 0x7ffff76a0400 abort type <function_type 0x7ffff77b5690 type <void_type 0x7ffff779fe70 void> QI size <integer_cst 0x7ffff778cfa0 constant 8> unit size <integer_cst 0x7ffff778cfc0 constant 1> align 8 symtab 0 alias set -1 canonical type 0x7ffff77b5690 arg-types <tree_list 0x7ffff77933e8 value <void_type 0x7ffff779fe70 void>>> addressable volatile used nothrow public external built-in decl_2 decl_5 decl_6 QI file <built-in> line 0 col 0 align 8 built-in BUILT_IN_NORMAL:BUILT_IN_ABORT context <function_decl 0x7ffff76a0200 main> attributes <tree_list 0x7ffff7827d98> chain <function_decl 0x7ffff76a0300 exit type <function_type 0x7ffff77b7b28> addressable volatile used nothrow public external built-in decl_2 decl_5 decl_6 QI file <built-in> line 0 col 0 align 8 built-in BUILT_IN_NORMAL:BUILT_IN_EXIT context <function_decl 0x7ffff76a0200 main> attributes <tree_list 0x7ffff782bcd0>>> supercontext <function_decl 0x7ffff76a0200 main type <function_type 0x7ffff7685738 type <integer_type 0x7ffff779f498 int> QI size <integer_cst 0x7ffff778cfa0 8> unit size <integer_cst 0x7ffff778cfc0 1> align 8 symtab 0 alias set -1 canonical type 0x7ffff77b51f8> public static QI file a.c line 26 col 5 align 8 initial <block 0x7ffff7692320> result <result_decl 0x7ffff7797780 D.1598 type <integer_type 0x7ffff779f498 int> ignored SI file a.c line 26 col 5 size <integer_cst 0x7ffff77a4160 constant 32> unit size <integer_cst 0x7ffff778cf00 constant 4> align 32> struct-function 0x7ffff768f1c8>> $22 = void (gdb) p debug_tree (0x7ffff7692280) <block 0x7ffff7692280 used vars <function_decl 0x7ffff76a0100 abort type <function_type 0x7ffff77b5690 type <void_type 0x7ffff779fe70 void> QI size <integer_cst 0x7ffff778cfa0 constant 8> unit size <integer_cst 0x7ffff778cfc0 constant 1> align 8 symtab 0 alias set -1 canonical type 0x7ffff77b5690 arg-types <tree_list 0x7ffff77933e8 value <void_type 0x7ffff779fe70 void>>> addressable volatile used nothrow public external built-in decl_2 decl_5 decl_6 QI file <built-in> line 0 col 0 align 8 built-in BUILT_IN_NORMAL:BUILT_IN_ABORT context <function_decl 0x7ffff76a0000 f> attributes <tree_list 0x7ffff7827d98>> supercontext <block 0x7ffff76922d0 used supercontext <function_decl 0x7ffff76a0000 f type <function_type 0x7ffff77b69d8> addressable used public static decl_5 QI file a.c line 4 col 5 align 8 initial <block 0x7ffff76922d0> arguments <parm_decl 0x7ffff7795880 i> result <result_decl 0x7ffff7797300 D.1587> (mem:QI (symbol_ref:DI ("f") [flags 0x3] <function_decl 0x7ffff76a0000 f>) [0 S1 A8]) struct-function 0x7ffff768f130> subblocks <block 0x7ffff7692280>>> Note that there are two declarations of abort() in two lists connected by TREE_CHAIN. Now this gets completely messed up in LTO streaming. We identify all builtin decls and consequentely we mess up the linked lists producing completely nonsential BLOCK lists. Honza int f(int i) { switch (i) { case -2: return 33; case -1: return 0; case 0: return 7; case 1: return 4; case 2: return 3; case 3: return 15; case 4: return 9; default: abort (); } } int main() { if (f(-1)) abort (); exit (0); }