[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