http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36861
Richard Guenther <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |INVALID --- Comment #37 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-01-18 15:19:05 UTC --- Ok, with -O1 -fno-tree-loop-im as basic flags -fno-tree-dse makes the difference for the segfault when we remove static void boost::intrusive::avltree_algorithms<NodeTraits>::rebalance_after_i nsertion(boost::intrusive::avltree_algorithms<NodeTraits>::node_ptr, boost::intr usive::avltree_algorithms<NodeTraits>::node_ptr) [with NodeTraits = boost::intru sive::avltree_node_traits<boost::interprocess::offset_ptr<void>, false>, boost:: intrusive::avltree_algorithms<NodeTraits>::node_ptr = boost::interprocess::offse t_ptr<boost::intrusive::avltree_node<boost::interprocess::offset_ptr<void> > >] (struct node_ptr & restrict header, struct node_ptr & restrict x) { long int D.64530; @@ -8290,7 +7992,6 @@ p.19_2156 = (long int) D.64522_2154; D.64529_2157 = (long int) D.64513_2150; D.64530_2158 = p.19_2156 - D.64529_2157; - MEM[(struct offset_ptr *)D.64515_2149].m_offset = D.64530_2158; if (D.64530_2158 == 1) goto <bb 746>; else this pointer is believed to point to D.64515_2149, points-to NULL, points-to vars: { D.57715 CAST_RESTRICT.445 } (includes restrict tags) computed from <bb 742>: n_2143 = (struct node_ptr & restrict) &D.57715; p_2144 = (struct node_ptr & restrict) &D.57716; D.64517_2145 = D.57715.m_offset; D.64516_2147 = (long unsigned int) D.64517_2145; D.64515_2148 = n_2143 + D.64516_2147; <bb 743>: # D.64515_2149 = PHI <0B(739), D.64515_2148(742)> which confirms the points-to calculation. But the compressed AVL tree thinks it can represent a pointer to a global object by using the address of a local variable and the difference between the address of the global and the local. Which it of course cannot according to the C++ standard. D.57715.m_offset is set by <bb 740>: p.19_2139 = (long int) D.64504_2137; D.64508_2140 = (long int) &D.57715; D.64509_2141 = p.19_2139 - D.64508_2140; D.57715.m_offset = D.64509_2141; if (D.64509_2141 == 1) goto <bb 741>; else goto <bb 742>; and we have <bb 737>: boost::interprocess::offset_ptr<boost::intrusive::avltree_node<boost::interprocess::offset_ptr<void> > >::offset_ptr (&D.57716, &root); D.64502_2134 = MEM[(const struct offset_ptr *)header_2(D)].m_offset; if (D.64502_2134 != 1) goto <bb 738>; else goto <bb 739>; <bb 738>: D.64503_2136 = (long unsigned int) D.64502_2134; D.64504_2137 = header_2(D) + D.64503_2136; where header_2(D) is a parameter, struct node_ptr & restrict header. So Boost AVL expects us to compute whatever header points-to as points-to set of D.64515_2149 with no backing from the standard that we are required to do that. If we were able to "optimize" the code back to base the address on header it would of course work (by luck). For extern void abort (void); struct X { unsigned long offset; }; void foo (char *p) { struct X a; char tmp, *q; a.offset = p - &tmp; if (a.offset == 1) abort (); q = &tmp + a.offset; *q = 0; } already early DCE kills the store (the above is what compressed AVL does). Thus, this testcase is invalid. Resulting performance is irrelevant.