C++: Fix handling of std::va_list that is used as a function parameter

In the Unix ABI, `std::va_list` is defined as `typedef struct __va_list_tag { ... } va_list[1];`, which means that any `std::va_list` used as a function parameter decays to `struct __va_list_tag*`. Handling this actually made the QL code slightly cleaner. The only tricky bit is that we have to determine what type to use as the actual `va_list` type when loading, storing, or modifying a `std::va_list`. To do this, we look at the type of the argument to the `va_*` macro. A detailed QLDoc comment explains the details.

I added a test case for passing a `va_list` as an argument, and then manipulating that `va_list` in the callee.
This commit is contained in:
Dave Bartolomeo
2020-03-20 12:53:09 -04:00
parent bf284514fc
commit 82e2816915
5 changed files with 3834 additions and 3688 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -885,6 +885,14 @@ void FuncPtrConversions(int(*pfn)(int), void* p) {
pfn = (int(*)(int))p;
}
void VAListUsage(int x, __builtin_va_list args) {
__builtin_va_list args2;
__builtin_va_copy(args2, args);
double d = __builtin_va_arg(args, double);
float f = __builtin_va_arg(args, int);
__builtin_va_end(args2);
}
void VarArgUsage(int x, ...) {
__builtin_va_list args;
@@ -894,6 +902,7 @@ void VarArgUsage(int x, ...) {
double d = __builtin_va_arg(args, double);
float f = __builtin_va_arg(args, int);
__builtin_va_end(args);
VAListUsage(x, args2);
__builtin_va_end(args2);
}

File diff suppressed because it is too large Load Diff