Bug 82791 - Inconsistency with member function pointer access
Summary: Inconsistency with member function pointer access
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
Depends on:
Blocks: pmf, ptmf
  Show dependency treegraph
 
Reported: 2017-11-01 09:09 UTC by Longinus Ulyanovsky
Modified: 2021-07-23 21:39 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-07-23 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Longinus Ulyanovsky 2017-11-01 09:09:03 UTC
Consider this code:

#include <typeinfo>
struct Foo
{
    void Bar();
};
int main()
{
    Foo obj;
    auto mfp = &Foo::Bar;

    auto foo = typeid(obj.*mfp).name(); //returns "void ()"
    auto bar = (void(*)(void)) (obj.*mfp); //cast succeeds
    auto baz = sizeof(obj.*mfp); //returns 1

    decltype(obj.*mfp) qux; //does not compile
    auto quux = obj.*mfp; //cannot deduce type
}

Compilation fails with the messages "error: invalid use of non-static member function of type 'void (Foo::)()'" and "error: unable to deduce 'auto' from 'obj.*mfp'" while all other expressions succeed with only casting and sizeof generating warnings.
"Noexcept" also succeeds, and probably other operators I did not test.

Both Clang and Zapcc reject the whole program.
ICC rejects everything except the cast.
MSVC rejects everything except the access in typeid and noexcept.

This does not follow N4700 ยง8.5.6 "If the result of .* or ->* is a function, then that result can be used only as the operand for the function call
operator ()."
But if we ignore this, this looks like an inconsistency that could be solved by authorizing 'auto' and 'decltype' to deduce "void(*)(void)", aligning with 'typeid'.
I don't understand what 'sizeof' does in this case so I won't comment on that.
Comment 1 Andrew Pinski 2021-07-23 21:39:18 UTC
With -pedantic-errors only:
auto foo = typeid(obj.*mfp).name(); //returns "void ()"

is accepted.

The rest is not.

GCC does have an extension converting PMF to a pointer function which is definitely happening here.