[cfe-dev] Variadic builtin strangeness (and an odd vfprintf!)

Charlie Turner charlesturner7c5 at gmail.com
Thu Apr 9 07:00:38 PDT 2015


I have a patch attached for this issue that allows you do declare


On 1 April 2015 at 15:58, Charlie Turner <charlesturner7c5 at gmail.com> wrote:
> Hello everyone,
>
> I'm trying to sort out https://llvm.org/bugs/show_bug.cgi?id=20958 --
> but struggling.
>
> For the particular case of __builtin_isnan (the C99 math macros in
> this section are strange too), it is defined as,
>
> BUILTIN(__builtin_isnan, "i.", "nc")
>
> That's how it should look. Unfortunately, ASTContext::GetBuiltinType
> treats an argument list with "..." as its sole member specially,
>
>   if (ArgTypes.empty() && Variadic) return
>     getFunctionNoProtoType(ResType, EI);
>
> Which essentially generates a declaration like,
>
> int __builtin_isnan();
>
> That works for double and long double (but not float (default
> promotions...)) in C, and in C++
> it's a very strange declaration for this builtin!
>
> Once you fix this and make Clang generate the correct (magic)
> prototype of
>
> int __builtin_isnan(...);
>
> which Sema::SemaBuiltinFPClassification expects it to take, the bug in
> PR20958 goes away, we can declare,
>
> int __builtin_isnan(T);
>
> for T in (double, long double, float).
>
> Unfortunately, we get some interesting test errors:
>
> CodeGen/builtin-ms-noop.cpp
>
> /work/llvm-gitsvn/tools/clang/test/CodeGen/builtin-ms-noop.cpp:11:17:
> error: cannot pass object of non-POD type 'A' through variadic
> function; call will abort at runtime
>   return __noop(A());
>
> The documentation for __noop says that the argument list should be
> parsed but no code should be generated. This is where my knowledge of
> cfe breaks down -- it seems like the implementation of this intrinsic
> as as a variadic builtin is wrong, but I would appreciate pointers on
> how to fix that, or indeed if I'm barking up the wrong tree.
>
> The other test errors uncovered a strange implementation of vfprintf,
>
> LIBBUILTIN(vfprintf, "i.",        "fP:1:", "stdio.h", ALL_LANGUAGES)
>
> That should of course be,
>
> LIBBUILTIN(vfprintf, "iP*cC*a", "fP:0:", "stdio.h", ALL_LANGUAGES)
>
> but the reason for doing it this way is because of autoconf weirdness,
>
> http://llvm.org/viewvc/llvm-project?view=revision&revision=72760
>
> I'm not sure about the rationale for the above commit. Can anyone
> with context help me understand it?
>
> I note that in GCC's own builtins.def file (you'd think they would
> get autoconf right!), the type of vfprintf is int ()(FILE*, const
> char *, va_list) as I expect. Maybe GCC has workarounds elsewhere.
>
> Clues? Thanks for reading!
>
> - Charlie.



More information about the cfe-dev mailing list