https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65233
--- Comment #8 from Matthias Klose <doko at gcc dot gnu.org> --- this is the testcase from ardour3: $ g++ -c -g -O3 -fPIC track3.ii track3.ii: In member function 'void F::apply(void (Track::*)(T, void*), T, void*) [with T = bool]': track3.ii:108:1: internal compiler error: Segmentation fault F::apply (void (Track::*p1) (T, void *), T p2, void *) ^ Please submit a full bug report, with preprocessed source if appropriate. $ cat track3.ii namespace std { template < typename _Tp > void swap (_Tp p1, _Tp & p2) { p2 = p1; } template < typename _Tp > struct A { _Tp & operator* (); }; template < typename _Tp > class B { public: typedef A < _Tp > iterator; }; } int a; class C { int use_count_; public: virtual void destroy (); void release () { if (use_count_) destroy (); } }; class shared_count { C *pi_; public: shared_count ():pi_ () { } ~shared_count () { if (pi_) pi_->release (); } shared_count (shared_count const &p1):pi_ (p1.pi_) { if (pi_) __sync_fetch_and_add (&a, 1); } void swap (shared_count & p1) { C *b = p1.pi_; p1.pi_ = pi_; pi_ = b; } }; template < class T > class D { typedef D this_type; public: typedef T element_type; D () { } template < class Y > D (D < Y > p1, element_type * p2):px (p2), pn (p1.pn) { } D & operator= (D p1) { this_type (p1).swap (*this); return *this; } element_type *get () { } typedef element_type *this_type::*unspecified_bool_type; operator unspecified_bool_type () { return px ? 0 : &this_type::px; } void swap (D & p1) { std::swap (px, p1.px); pn.swap (p1.pn); } element_type *px; shared_count pn; }; class Track; template < class, class U > D < Track > dynamic_pointer_cast (D < U > &p1) { Track *p; return p ? D < Track > (p1, p) : D < Track > (); } class F { public: template < class T > void apply (void (Track::*)(T, void *), T, void *); }; class G { protected: F _route_group; }; class Track:G { void prep_record_enabled (bool, void *); }; template < class T > void F::apply (void (Track::*p1) (T, void *), T p2, void *) { for (std::B < D < int > >::iterator i;;) { D < Track > c; if (c = dynamic_pointer_cast < Track > (*i)) (c.get ()->*p1) (p2, this); } } void Track::prep_record_enabled (bool p1, void *) { _route_group.apply (&Track::prep_record_enabled, p1, &_route_group); }