[cfe-dev] Variadic builtin strangeness (and an odd vfprintf!)
Charlie Turner
charlesturner7c5 at gmail.com
Wed Apr 1 07:58:33 PDT 2015
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