Hi! On this testcase the TU is -O0, but a particular function is -O2. The -O0 means odr_hash isn't created, but during fold_gimple_call we call possible_polymorphic_call_targets because -fdevirtualize is true in the current function (as it is -O2) and ICE because we assume odr_hash can be used safely.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2014-02-04 Jakub Jelinek <ja...@redhat.com> PR ipa/59947 * ipa-devirt.c (possible_polymorphic_call_targets): Fix a comment typo and formatting issue. If odr_hash hasn't been created, return vNULL and set *completep to false. * g++.dg/opt/pr59947.C: New test. --- gcc/ipa-devirt.c.jj 2014-02-03 08:53:12.000000000 +0100 +++ gcc/ipa-devirt.c 2014-02-03 19:23:01.130257924 +0100 @@ -1276,7 +1276,7 @@ devirt_variable_node_removal_hook (varpo temporarily change to one of base types. INCLUDE_DERIVER_TYPES make us to walk the inheritance graph for all derivations. - If COMPLETEP is non-NULL, store true if the list is complette. + If COMPLETEP is non-NULL, store true if the list is complete. CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry in the target cache. If user needs to visit every target list just once, it can memoize them. @@ -1295,7 +1295,7 @@ possible_polymorphic_call_targets (tree static struct cgraph_node_hook_list *node_removal_hook_holder; pointer_set_t *inserted; pointer_set_t *matched_vtables; - vec <cgraph_node *> nodes=vNULL; + vec <cgraph_node *> nodes = vNULL; odr_type type, outer_type; polymorphic_call_target_d key; polymorphic_call_target_d **slot; @@ -1303,6 +1303,13 @@ possible_polymorphic_call_targets (tree tree binfo, target; bool final; + if (!odr_hash.is_created ()) + { + if (completep) + *completep = false; + return nodes; + } + type = get_odr_type (otr_type, true); /* Lookup the outer class type we want to walk. */ --- gcc/testsuite/g++.dg/opt/pr59947.C.jj 2014-02-03 19:26:45.041118010 +0100 +++ gcc/testsuite/g++.dg/opt/pr59947.C 2014-02-03 19:26:07.000000000 +0100 @@ -0,0 +1,34 @@ +// PR ipa/59947 +// { dg-do compile } +// { dg-options "-O0 -std=c++11" } + +#pragma GCC optimize ("O2") +template <typename T> +inline void +foo (T & a) noexcept { T tmp = static_cast <T &&> (a); }; +struct A +{ + A () noexcept : a (1), b (1) {} + virtual void c () noexcept = 0; + void d () noexcept { c (); } + int a; + int b; +}; +struct B +{ + ~B () noexcept { e->d (); } + A *e; +}; +template <typename T> +struct C +{ + B f; +}; +struct D {}; +template <typename T> +struct E +{ + void bar () { foo (g); } + C <D> g; +}; +template class E <char>; Jakub