Clang: Erroneous behavior on windows

Dear All,

I’m using clang on windows under Visual Studio 2015 CTP 6. I’ve tried both the official binaries: http://llvm.org/releases/download.html, and this one: http://sourceforge.net/projects/clangonwin/postdownload?source=dlp , and with all of them the following code fails to compile for me, but it is expected to be correct (based on stackoverflow), and it does comile with VS, and both clang and gcc on http://gcc.godbolt.org/

The code is the following, its is compiled with the additional flag: -Xclang -std=c++14

//-----------------------------------------------
template
decltype(auto) deduce(F f){ return &decltype(f)::operator(); }

template<typename C, typename R, typename A> decltype(auto)
signaturehelper( R(C::*f)(A)const ) { return R(); }

int main()
{
auto l = (int x){return x*2;};
decltype(signaturehelper(deduce(l))) p;
}
//--------------------------------

It fails with:
decltype(signaturehelper(deduce(l))) p;
^~~~~~~~~~~~~~~
note: candidate template ignored: substitution failure [with C = (lambda at main.cpp:9:11), R = float, A = int]
decltype(auto) signaturehelper(R(C::*f)(A)const) { return R(); }

Other workarounds show that the compiler believes that the lambda has no member ::operator().

Am I overlooking something, or there is some problem with some settings / flags or the Windows build?

Thanks in advance,

Daniel

Dear All,

I'm using clang on windows under Visual Studio 2015 CTP 6. I've tried both
the official binaries: LLVM Download Page, and this
one: Find out more about ClangOnWin | SourceForge.net ,
and with all of them the following code fails to compile for me, but it is
expected to be correct (based on stackoverflow), and it does comile with
VS, and both clang and gcc on http://gcc.godbolt.org/

The code is the following, its is compiled with the additional flag:
-Xclang -std=c++14

//-----------------------------------------------
template<typename F>
  decltype(auto) deduce(F f){ return &decltype(f)::operator(); }

template<typename C, typename R, typename A> decltype(auto)
  signaturehelper( R(C::*f)(A)const ) { return R(); }

int main()
{
  auto l = (int x){return x*2;};
  decltype(signaturehelper(deduce(l))) p;
}
//--------------------------------

It fails with:
decltype(signaturehelper(deduce(l))) p;
               ^~~~~~~~~~~~~~~
note: candidate template ignored: substitution failure [with C = (lambda
at main.cpp:9:11), R = float, A = int]
decltype(auto) signaturehelper(R(C::*f)(A)const) { return R(); }

Other workarounds show that the compiler believes that the lambda has no
member ::operator().

Am I overlooking something, or there is some problem with some settings /
flags or the Windows build?

Seems OK on 64-bit targets but fails for targets which have distinct
cdecl/thiscall calling conventions like 32-bit mingw and 32-bit msvc.

Reid, any ideas?

I've had exactly the same problem when I tried to find the argument type of a lambda. Here's how I worked around it:

         template <typename R, typename C, typename Arg, typename... Args>
         struct FirstArgumentImpl<R (C::*)(Arg, Args...) const>
         {
             using type = Arg;
         };
         // for Clang on Windows
         template <typename R, typename C, typename Arg, typename... Args>
         struct FirstArgumentImpl<R (__cdecl C::*)(Arg, Args...) const>
         {
             using type = Arg;
         };

The issue appears to be that Clang gives the lambda's operator() a __cdecl calling convention instead of the default member __thiscall calling convention.

Sebastian

With MSVC compatibility turned on, we should be generating an
operator() for every calling convention for non-capturing lambdas.

http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2015/02/20/10594680.aspx

~Aaron

So, this was a bug. We forgot to make lambda call operators thiscall. They’re C++ method decls, and should clearly use that convention. I changed in r233023 to reflect that.

Thanks for the report!