[LLVMbugs] [Bug 19588] New: [Windows] decltype(&T::operator()) weird errors when T is decltype(lambda expression)

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon Apr 28 12:27:28 PDT 2014


http://llvm.org/bugs/show_bug.cgi?id=19588

            Bug ID: 19588
           Summary: [Windows] decltype(&T::operator()) weird errors when T
                    is decltype(lambda expression)
           Product: clang
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P
         Component: Frontend
          Assignee: unassignedclangbugs at nondot.org
          Reporter: szdarkhack at hotmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

I have implemented a small function_traits library in VS2013. It works fine
when compiled with MSVC, as well as a bunch of compilers I've tested online
(including clang). So I decided to try to compile it using the latest windows
build of clang (3.5, r203967). The code failed to compile.

The error occurs in my code, so it is most likely not related to any MS library
compatibility issues (the library only lightly depends on type_traits which
should work fine in this version). Most of the work is done by template
specializations.

It all comes down to instantiating the following template:

template <typename T>
struct function_traits
    : public function_traits<decltype(&T::operator())>
{};

with T being decltype(lambda), where lambda = [](int){}. This generates an
error as follows:

error: type 'void (<lambda at main.cpp:32:16>::*)(int) const' cannot be used
prior to '::' because it has no members
: public function_traits<decltype(&T::operator())>
                                   ^
note: in instantiation of template class 'function_traits<void (<lambda at
main.cpp:32:16>::*)(int) const>' requested here
: public function_traits<decltype(&T::operator())>
         ^
note: in instantiation of template class 'function_traits<<lambda at
main.cpp:32:16> >' requested here

This is extremely weird. Since it's getting a member pointer, I think it's
going through the same template specialization twice and the error occurs the
second time around. The problem is, there is a perfectly fine member function
pointer specialization to choose just a few lines below:

template <typename Class, typename Ret, typename... Args>
struct function_traits<Ret(Class::*)(Args...) const>
  : /* stuff */
{ /* more stuff */ };

Even worse, an actual struct with operator() with the same signature as the
lambda goes through the templates just fine, choosing the specialization above
the second time around.

While trying to figure what could be going wrong here, I was even more
surprised to find that the following static assertion fails:

int main()
{
    auto lambda = [](int){};
    using Type = decltype(lambda);
    static_assert<std::is_same<void(Type::*)(int) const,
        decltype(&Type::operator())>::value, "");
    return 0;
}

Note that all of the code (function traits + this last test) compiles fine with
MSVC and as many online compilers as I could try, including gcc 4.7 and clang
3.3.

-- 
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/20140428/fe511ec6/attachment.html>


More information about the llvm-bugs mailing list