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.

Reply via email to