llvm-project icon indicating copy to clipboard operation
llvm-project copied to clipboard

accessing member in trailing return type of locally defined friend function triggers error with clang

Open wanghan02 opened this issue 1 year ago • 2 comments

Example code as below or on Godbolt. All friend functions compile with GCC and Visual Studio. Clang fails when trying to access S<T>::foo() in trailing return type. The question could also be found on StackOverflow.

#include <concepts>

template<typename T>
struct S {
    T m_t;

    T const& foo() const& { return m_t; }

    auto mem_fn_trailing_return(S const& s) -> decltype(s.foo()) {
        return s.foo();
    }

    friend auto bar_auto(S const& s) {
        return s.foo();
    }

    friend decltype(auto) bar_decltype_auto(S const& s) {
        return s.foo();
    }

    friend decltype(auto) bar_requires(S const& s) requires std::same_as<T const&, decltype(s.foo())> {
        return s.foo();
    }

    friend auto bar_trailing_return(S const& s) -> decltype(s.foo()) { // clang error: member access into incomplete type 'const S<int>'
        return s.foo();
    }
};

S<int> s{1};

According to expr.ref#4:

Otherwise, the object expression shall be of class type. The class type shall be complete unless the class member access appears in the definition of that class. [Note 3: The program is ill-formed if the result differs from that when the class is complete ([class.member.lookup]). — end note] [Note 4: [basic.lookup.qual] describes how names are looked up after the . and -> operators. — end note]

The class member access in trailing return type of a locally defined friend function does appear in the definition of that class. IMO Clang should allow it.

wanghan02 avatar Jun 26 '23 13:06 wanghan02

@llvm/issue-subscribers-clang-frontend

llvmbot avatar Jun 26 '23 13:06 llvmbot

We have some other bugs around complete class contexts: https://github.com/llvm/llvm-project/issues/58245

shafik avatar Jun 26 '23 16:06 shafik

CWG1836

In a trailing-return-type, the class being defined is not required to be complete for purposes of class member access

pepsiman avatar Dec 11 '23 19:12 pepsiman