[cfe-dev] clang for Windows problem in Boost.TypeTraits

Edward Diener eldlistmailingz at tropicsoft.com
Fri Oct 4 23:40:42 PDT 2013


On 10/3/2013 6:57 AM, Hans Wennborg wrote:
> I've filed http://llvm.org/bugs/show_bug.cgi?id=17464 to track this.

Someone else had already files http://llvm.org/bugs/show_bug.cgi?id=12535 .

>
>   - Hans
>
> On Wed, Oct 2, 2013 at 4:30 AM, Paweł Bylica <chfast at gmail.com> wrote:
>>
>>
>>
>> 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
>>>> <mailto: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.
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>





More information about the cfe-dev mailing list