[cfe-dev] clang for Windows problem in Boost.TypeTraits
Paweł Bylica
chfast at gmail.com
Wed Oct 2 04:30:09 PDT 2013
On Wed, Oct 2, 2013 at 1:01 PM, Edward Diener <
eldlistmailingz at tropicsoft.com> wrote:
> On 10/1/2013 9:13 PM, Reid Kleckner wrote:
>
>> On Tue, Oct 1, 2013 at 8:27 PM, Edward Diener
>> <eldlistmailingz at tropicsoft.**com <eldlistmailingz at tropicsoft.com>
>> <mailto:eldlistmailingz@**tropicsoft.com <eldlistmailingz at tropicsoft.com>>>
>> wrote:
>>
>> On 10/1/2013 2:16 PM, Nico Rieck wrote:
>>
>> On 30.09.2013 05:29, Edward Diener wrote:
>>
>> I could not find anything in the C++11 standard about
>> variadic functions
>> and calling conventions. Is this a "bug" with clang under
>> Windows or
>> should Boost.TypeTraits not try to allow __fastcall in this
>> situation
>> when compiling with clang under Windows ?
>>
>>
>> I think it's a defect in both. Boost should drop the overloaded
>> vararg
>> is_function_ptr_tester specializations with non-standard calling
>> conventions as they are never used. When MSVC encounters a vararg
>> function with stdcall/fastcall it silently converts it to cdecl.
>>
>>
>> is there a way to test that this is what it actually does ?
>>
>>
>> First, compiling the code "void __fastcall foo() { }" produces the
>> symbol ?foo@@YAXZZ which demangles to 'void __cdecl foo(...)'.
>>
>> Second, you can call it and verify that the assembly is adhering to the
>> usual C calling convention.
>>
>
> Understood.
>
>
>
>>
>> Though
>> for compatibility with (broken) MSVC code Clang should match that
>> behavior if desired.
>>
>>
>> The issue is that MSVC will accept the declaration without a
>> compiler error as part of its extensions no matter what it may
>> silently do. So if clang in Windows also defines the _MSC_EXTENSIONS
>> macro it should ideally emulate MSVC in that regard.
>>
>>
>> I agree, this is a reasonable expectation, but I would classify this bug
>> as low priority, since variadic fastcall doesn't make sense.
>>
>
> I have brought this last point up in the Boost developers forum.
>
>
>
>> I will however mention in the Boost developers forum that it might
>> be good to drop the overloaded vararg specializations with
>> non-standard calling conventions for MSVC. Or Boost could decide to
>> test for clang and not allow it when using clang.
>>
>>
>> Boost probably should drop this specialization. It's actually declaring
>> the __cdecl specialization after the implicit adjustment. When I
>> attempt to define a specialization for both 'R (__fastcall *)(...)' and
>> 'R (__cdecl *)(...)' in the same TU, I get a compiler error from MSVC:
>> t.cpp(7) : error C2995: 'void is_function_template(R (__cdecl *)(...))'
>> : function template has already been defined
>> t.cpp(5) : see declaration of 'is_function_template'
>>
>> extern "C" int printf(const char *fmt, ...);
>> template <typename T>
>> void is_function_template(T t) { printf("no\n"); }
>> template <typename R>
>> void is_function_template(R (__cdecl *fptr)(...)) { printf("cdecl\n"); }
>> template <typename R>
>> void is_function_template(R (__fastcall *fptr)(...)) {
>> printf("fastcall\n"); }
>>
>
> Yet just the declarations in the Boost header file does not give an MSVC
> compiler error:
>
>
> template <class R >
> yes_type is_function_ptr_tester(R (__fastcall*)( ...));
> template <class R >
> yes_type is_function_ptr_tester(R (__cdecl*)( ...));
>
> in the same TU. But I will bring up in the Boost forum that actually
> trying to define separate implementations in the same TU with those
> signatures does generate an MSVC error.
>
>
I did some research on pointers to __fastcall variadic functions. Type
declaration of such pointer is accepted by MSVS, but it means a pointer to
__cdecl function.
In other words:
void (*fp)(...)
is the same as
void (__fastcall*fp)(...)
and
void (__stdcall*fp)(...)
You can even write:
void __stdcall test(...) {}typedef void (__fastcall*fp)(...);fp f = &test;
One more proof:
void (__fastcall*f)(...) = 1;
produces error: cannot convert from 'int' to 'void (__cdecl *)(...)'.
I believe this template specialization really make no sense.
As far as clang is considered, it does not accept pointers to __fastcall
variadic function but accepts pointers for __stdcall variadic function.
Such template specialization exists in the same Boost file.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131002/e7bfd48c/attachment.html>
More information about the cfe-dev
mailing list