The question \'Pass va_list or pointer to va_list?\' has an answer which quotes the standard (ISO/IEC 9899:1999 - §7.15 \'Variable arguments , f
As others have noted, this issue manifests itself when va_list is an array type. This is allowed by the standard, which only says that va_list must be an "object type".
You can fix the test_val() function like so:
static void test_val(const char *fmt, va_list args)
{
va_list args_copy;
/* Note: This seemingly unnecessary copy is required in case va_list
* is an array type. */
va_copy(args_copy, args);
test_ptr(fmt, &args_copy);
va_end(args_copy);
}