va_arg problem on x86_64, fix and test-case


I'm new to clang.

I tried compiling a code base which uses a va_list argument and got an
error. The following snippet isolates the problem and complements

void f4(int a, __builtin_va_list ap)
    char* r = __builtin_va_arg(ap, char*);

Errors seen but not expected:
  Line 30: first argument to 'va_arg' is of type 'struct __va_list_tag
*' and not 'va_list'

This seems to be caused by either 1) a bad declaration of
__va_list_tag or 2) faulty logic on Sema::ActOnVAArg() [it uses
CheckAssignmentConstraints() to check the compatibility].

The "declaration" of __builtin_va_list on x86_64 is:

static const char* getX86_64VAListDeclaration() {
    "typedef struct __va_list_tag {"
    " unsigned gp_offset;"
    " unsigned fp_offset;"
    " void* overflow_arg_area;"
    " void* reg_save_area;"
    "} __builtin_va_list[1];";

Is there a reason for it to be declared as a single element array?
Removing the array declaration fixes the problem. The fix does not
seem to introduce any additional problems, as tested with "make test".

So, my questions are the following:

- why the array?
- Is reducing the declaration to a simple struct the correct fix?
- The getPPCVAListDeclaration() might have the same problem. Can anyone confirm?
- Is my the test case OK?
- should I send a patch?
- should I also try to implement/fix the following?

llc: X86ISelLowering.cpp:5223: llvm::SDOperand
llvm::SelectionDAG&): Assertion `0 && "VAArgInst is not yet
implemented for x86-64!"' failed.

Thanks for your insights.