"private" access specifier not respected in overloaded SFINAE context · Issue #107629 · llvm/llvm-project (original) (raw)

Given the following code (run it here), where "Base::Whatever" is private (both overloads), why does Clang correctly display false except when (both) "T" is "Derived" and function "Whatever" is overloaded. This appears to be erroneous behavior but it's a fuzzy area in this context (but see behavior table further below):

#include #include

class Base { private: // Defaults to this anyway but being explicit

void Whatever(int)
{
}

void Whatever(int, float)
{
}

};

class Derived : public Base { };

template <typename T, typename U, typename = void> struct HasFuncWhatever : std::false_type { };

template <typename T, typename U> struct HasFuncWhatever<T, U, std::void_t<decltype(static_cast<U T::*>(&T::Whatever))> > : std::true_type { };

int main() { using T = Derived; using U = void (int); std::cout << std::boolalpha << HasFuncWhatever<T, U>::value; return 0; }

Here's the behavior of the 3 compilers I tested (only MSVC presumably gets it right):

T          "Whatever" overloaded?   Clang Displays    MSVC Displays     GCC Displays       
-          ----------------------   --------------    -------------     ------------
Base       No                       false (correct)   false (correct)   false (correct)    
Base       Yes                      false (correct)   false (correct)   Fails compilation due to private access (incorrect)
Derived    No                       false (correct)   false (correct)   false (correct)  
Derived    Yes                      true (incorrect)  false (correct)   Fails compilation due to private access (incorrect)

Unless this is explicitly mentioned in the standard somewhere, or it's considered undefined behavior (implementation defined), the call to "&T::Whatever" in the partial specialization of "HasFuncWhatever" should always presumably fail since "Whatever" is private. The primary template should therefore always kick in so the code should always display false.