http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46560

--- Comment #1 from Richard Guenther <rguenth at gcc dot gnu.org> 2010-11-26 
14:02:28 UTC ---
FAIL: 21_strings/basic_string/insert/char/1.cc execution test

is because we optimize away EH code.  A stripped-down testcase shows instead
of

Eh tree:
   3 cleanup land:{3,<L16>}
     6 cleanup
       7 cleanup land:{5,<L14>}
         11 try land:{7,<L11>} catch:{struct out_of_range},{}
         8 try land:{6,<L8>} catch:{struct out_of_range},{}

Eh tree:
   3 cleanup land:{3,<L14>}
     6 cleanup
       7 cleanup land:{5,<L12>}
         8 try land:{6,<L6>} catch:{(void *) &_ZTISt12out_of_range},{}

it's already broken at .044i.inline - one insert call doesn't have eh info.

I suspect that nothrow discovery is broken somehow.

Function found to be nothrow: insert
insert/19(-1) @0x7ffff5d1fdc0 (asm: _ZNSs6insertEmRKSsmm) (inline copy in
test01/5) (clone of insert/0) availability:local analyzed 29 time, 20 benefit
25 size, 12 benefit reachable local finalized inlinable
  called by: test01/5 (1.00 per call) (inlined)
  calls: __throw_out_of_range/8 insert/7 (1.00 per call)
  References:
  Refering this function:

but we have before propagate nothrow:

insert/19(-1) @0x7ffff5d1fdc0 (asm: _ZNSs6insertEmRKSsmm) (inline copy in
test01/5) (clone of insert/0) availability:local analyzed 29 time, 20 benefit
25 size, 12 benefit reachable local finalized inlinable
  called by: test01/5 (1.00 per call) (inlined)
  calls: __throw_out_of_range/8 insert/7 (1.00 per call)
  References:
  Refering this function:

__throw_out_of_range/8(-1) @0x7ffff5d1ec60 (asm: _ZSt20__throw_out_of_rangePKc)
availability:not_available reachable
  called by: insert/19 insert/0 (can throw external)
  calls:
  References:
  Refering this function:

insert/0(-1) @0x7ffff5d1e160 (asm: _ZNSs6insertEmRKSsmm) availability:available
analyzed 29 time, 20 benefit 25 size, 12 benefit reachable finalized inlinable
  called by: test01/5
  calls: insert/7 (1.00 per call) (can throw external) __throw_out_of_range/8
(can throw external)
  References:
  Refering this function:

so __throw_out_of_range/8 can throw.

During propagation visiting insert/19 we visit the edge to
__throw_out_of_range.
The edge has e->can_throw_external == 0, probably because:

  edge->can_throw_external
    = call_stmt ? stmt_can_throw_external (call_stmt) : false;

in cgraph.c which isn't exactly a conservative assumption.

(gdb) p e
$13 = (struct cgraph_edge *) 0x7ffff5d20548
(gdb) p e->caller
$14 = (struct cgraph_node *) 0x7ffff5d1fdc0
(gdb) p e->callee
$15 = (struct cgraph_node *) 0x7ffff5d1ec60

which is an inline clone edge.  I suppose cgraph_clone_edge should clone
the flags that depend on call_stmt as well.

That fixes it.

Reply via email to