https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66908
--- Comment #12 from Maxim Ostapenko <chefmax at gcc dot gnu.org> --- (In reply to Marek Polacek from comment #11) > Hmm, still can't reproduce even with vanilla trunk: > > A = A.0; > D.2679 = get.__pfn; > D.2680 = (long int) D.2679; > D.2681 = D.2680 & 1; > if (D.2681 == 0) goto <D.2682>; else goto <D.2683>; > <D.2682>: > iftmp.1 = get.__pfn; > goto <D.2684>; > <D.2683>: > D.2685 = get.__delta; > D.2686 = (sizetype) D.2685; > D.2687 = A + D.2686; > D.2688 = MEM[(int (*__vtbl_ptr_type) () * *)D.2687]; > D.2689 = get.__pfn; > D.2690 = (long int) D.2689; > D.2691 = D.2690 + -1; > D.2692 = (sizetype) D.2691; > D.2693 = D.2688 + D.2692; > iftmp.1 = *D.2693; > <D.2684>: > D.2694 = get.__delta; > D.2695 = (sizetype) D.2694; > D.2696 = A + D.2695; > result = iftmp.1 (D.2696); > operator delete (A); > D.2697 = result; > return D.2697; > > I don't see the shifts at all. And you should not, this is ARM - specific. From C++ ABI for the ARM Architecture: "3.2.1 Representation of pointer to member function The generic C++ ABI [GC++ABI] specifies that a pointer to member function is a pair of words <ptr, adj>. The least significant bit of ptr discriminates between (0) the address of a non-virtual member function and (1) the offset in the class’s virtual table of the address of a virtual function. This encoding cannot work for the ARM-Thumb instruction set where code addresses use all 32 bits of ptr. This ABI specifies that adj contains twice the this adjustment, plus 1 if the member function is virtual. The least significant bit of adj then makes exactly the same discrimination as the least significant bit of ptr does for Itanium. A pointer to member function is NULL when ptr = 0 and the least significant bit of adj is zero." Perhaps I should cook x86 reproducer.