Clang checks whether the type given to va_arg will automatically cause undefined behavior, but this check was issuing false positives for enumerations in C++. The issue turned out to be because typesAreCompatible() in C++ checks whether the types are *the same*, so this falls back on the type merging logic to see whether the types are mergable or not in both C and C++.
This issue was found by a user on code like:
typedef enum { CURLINFO_NONE, CURLINFO_EFFECTIVE_URL, CURLINFO_LASTONE = 60 } CURLINFO; ... __builtin_va_arg(list, CURLINFO); // warn about CURLINFO promoting to 'int' being UB in C++ but not C
Given that C++ defers to C for the rules around va_arg, the behavior should be the same in both C and C++ and not diagnose because int and CURLINFO are compatible types.
If we're not going to take advantage of the C notion of compatibility, might as well just check hasSameType().