On 8/11/23 04:48, Jakub Jelinek wrote:
On Fri, Aug 11, 2023 at 01:13:32AM +0200, Jakub Jelinek wrote:
Looking at the first uses of the builtin back in 90s in va*.h, it certainly
relied on array/function decay there (the macros would abort e.g. on
array_type_class, function_type_class and various other return values).
Looking at older versions of tgmath.h, I see just checks for 8/9 (i.e.
real/complex) and those woiuldn't be affected by any promotions/decay.
But newer versions of tgmath.h before __builtin_tgmath do check also for
1 and they would be upset if char wasn't promoted to int (including latest
glibc).
systemtap macros also use __builtin_classify_type and do check for pointers
but those seems to be prepared to handle even arrays.

So to sum it up, I think at least the original use of the builtin had a
strong reason to do the array to pointer etc. decay and argument promotion,
because that is what happens with the varargs too and the builtin is still
documented in the internals manual just for that purpose.  It is true GCC
doesn't use the builtin for that reason anymore, but there are numerous
uses in the wild, some might cope well with changing the behavior, others
less so.

+               cp_evaluated ev;
+               ++cp_unevaluated_operand;
+               ++c_inhibit_evaluation_warnings;

These three lines seem unnecessary for parsing a type.

I had a quick look at this and a reason to do at least some of this
is e.g. array types, __builtin_classify_type (int [foo () + whatever])
will not really evaluate foo () + whatever, all it will care about is that
it is an array, so emiting evaluation warnings for it would be weird.
cp_unevaluated_operand is harder to find out what all the effects are,
but e.g. warnings for missing member initializers in such expressions
isn't needed either.

Fair enough.  But you should only need a single line

cp_unevaluated ev;

The C++ bits are OK with that change.

Jason

Reply via email to