[LLVMbugs] [Bug 22121] Clang will not accept a conversion from a bound pmf(Pointer to member function) to a regular method pointer. Gcc accepts this.

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Thu Jul 30 11:10:57 PDT 2015


https://llvm.org/bugs/show_bug.cgi?id=22121

David Majnemer <david.majnemer at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|---                         |WONTFIX

--- Comment #3 from David Majnemer <david.majnemer at gmail.com> ---
(In reply to comment #2)
> (In reply to comment #1)
> > It's a non-conforming extension:
> > https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Bound-member-functions.html
> 
> Yes, it is. But there are two reasons for this to be implemented:
> 
> 1. Clang aims to be a GCC drop-in replacement and mimics GCC. If it does so,
> I would expect it to implement all GCC's extensions, at least this one,
> which is probably not so complex.

Clang aims to be as compatible as is reasonable but no closer.  There are some
very prominent GCC extensions which clang will *never* implement.

> 
> 2. This is a very important feature, which is impossible to replace with any
> other legal construct of the language. This is a huge oversight by the C++
> standard committee that this feature is not available in the language. The
> PMF (pointer to member function) is a much more complicated and not nearly
> as useful construct than a pointer to bound member function, yet the former
> is present in the language, and the latter still isn't.

The feature is fundamentally broken because pointers to member functions don't
result in accessing a vtable when the member function in question is
non-virtual.
Consider the following:
$ cat t.cpp
extern "C" int printf(const char *, ...);

struct A {
  char x;
  void f() { printf("A-in-B [A::f]: %p\n", this); }
};
struct X { virtual ~X() {} char y; };
struct B : X, A {};
extern B b;
typedef void (B::*b_mp)();
typedef void (*b_fptr)(B *);

b_fptr convert(B &b, b_mp mp){
  return (b_fptr)(b.*mp);
}

int main() {
  B b;
  b_mp mp = &A::f;
  printf("B:     [main]: %p\n", &b);
  printf("A-in-B [main]: %p\n", (A *)&b);
  (b.*mp)();
  convert(b, mp)(&b);
}
$ g++ -Wno-pmf-conversions t.cpp -o t && ./t
B:     [main]: 0x7ffde0a7c9f0
A-in-B [main]: 0x7ffde0a7c9f9
A-in-B [A::f]: 0x7ffde0a7c9f9
A-in-B [A::f]: 0x7ffde0a7c9f0

The last printf didn't correctly print out the address of the A-in-B subobject
of B.  This is because GCC can't rely on the fact that there exists a B-to-A
thunk which will perform the this adjustment for us.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150730/a52f9202/attachment.html>


More information about the llvm-bugs mailing list