Q:

Does va_arg use the pre- or post-mangled type as its second argument?

When using C-level variable arguments:
void  example( size_t length, ... )
{
    va_list  list;
    T        x;
    va_start( list, length );
    //...
    x = va_arg( list, T );
    //...
    va_end( list );
}

some types get altered when passed through the "...".  For example, a float becomes a double.  If T is such a type, am I supposed to put the original type or the mangled one into va_arg?
If the answer differs for C and C++ and/or Standard revisions, please indicate that.
(Quick glances around here suggest that the mangled type is supposed to be used. I hope not, since that's broken because it requires the user to compute the type, which is a pain if the original type is behind a type-alias, especially aliases that don't have a universal original, like size_t.  Hopefully, the title of my post is more searchable.)
(With more thought, I realize that the destination variable has to be declared with the mangled type. So using the mangled type in va_arg, if true, is less stupid than I thought. I get spoiled by C++11's auto sometimes.)

A:

If T is such a type, am I supposed to put the original type or the mangled one into va_arg?

If T is a type subject to promotion, then you are supposed to put in the converted type, else the program has undefined behavior.

If the answer differs for C and C++ and/or Standard revisions, please indicate that.

As far as I know, both C and C++ require this.

With more thought, I realize that the destination variable has to be declared with the mangled type

No, that's not a must. Since it is guaranteed that the "call" to the va_arg() macro will be of the type that you specify as its second argument, then something like
float f = va_arg(args, double);

will be perfectly fine, since va_arg(...) evaluates to an expression of type double, and that will then be implicitly converted to a float.

Edit: some standard quotes.
I. C99, 7.15.1.1.2:

[...] If there is no actual next argument, or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined [...].

II. C++11 working draft, 18.10.3:

The restrictions that ISO C places on the second parameter to the va_start() macro in header <stdarg.h> are different in this International Standard. The parameter parmN is the identifier of the rightmost parameter in the variable parameter list of the function definition (the one just before the ...). If the parameter parmN is declared with a function, array, or reference type, or with a type that is not compatible with the type that results when passing an argument for which there is no parameter, the behavior is undefined.

For me, the above (C++) quote doesn't really seem to be related to the behavior of default promotions; however, I think that by saying "the restrictions are different", they mean that they are the same except for the following [above] clause.

