Clang: Erroneous behavior on windows

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Clang: Erroneous behavior on windows

Daniel Berenyi
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<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?

Thanks in advance,
Daniel

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang: Erroneous behavior on windows

David Majnemer


On Sun, Mar 22, 2015 at 10:25 AM, Daniel Berenyi <[hidden email]> wrote:
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<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?
 

Thanks in advance,
Daniel

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang: Erroneous behavior on windows

Sebastian Redl
In reply to this post by Daniel Berenyi
On 3/22/2015 6:25 PM, Daniel Berenyi wrote:

> Dear All,
>
> //-----------------------------------------------
> 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(); }
>
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
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang: Erroneous behavior on windows

Aaron Ballman
On Mon, Mar 23, 2015 at 5:44 AM, Sebastian Redl
<[hidden email]> wrote:

> On 3/22/2015 6:25 PM, Daniel Berenyi wrote:
>>
>> Dear All,
>>
>> //-----------------------------------------------
>> 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(); }
>>
> 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.

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
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang: Erroneous behavior on windows

Daniel Berenyi
In reply to this post by Daniel Berenyi
Yes, Sebastian's workaround compiles fine.
Indeed, the compatibility flags do not mitigate the problem.

Daniel

>> The issue appears to be that Clang gives the lambda's operator() a __cdecl
>> calling convention instead of the default member __thiscall calling
>> convention.
>
>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

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang: Erroneous behavior on windows

Reid Kleckner-3
In reply to this post by Sebastian Redl
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!

On Mon, Mar 23, 2015 at 2:44 AM, Sebastian Redl <[hidden email]> wrote:
On 3/22/2015 6:25 PM, Daniel Berenyi wrote:
Dear All,

//-----------------------------------------------
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(); }

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

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev