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);
}

Reply via email to