[Sema] tolerate more promotion matches in format string checking
It's been reported that when using __attribute__((format)) on non-variadic functions, certain values that normally get promoted when passed as variadic arguments now unconditionally emit a diagnostic: ```c void foo(const char *fmt, float f) __attribute__((format(printf, 1, 2))); void bar(void) { foo("%g", 123.f); // ^ format specifies type 'double' but the argument has type 'float' } ``` This is normally not an issue because float values get promoted to doubles when passed as variadic arguments, but needless to say, variadic argument promotion does not apply to non-variadic arguments. While this can be fixed by adjusting the prototype of `foo`, this is sometimes undesirable in C (for instance, if `foo` is ABI). In C++, using variadic templates, this might instead require call-site fixing, which is tedious and arguably needless work: ```c++ template<typename... Args> void foo(const char *fmt, Args &&...args) __attribute__((format(printf, 1, 2))); void bar(void) { foo("%g", 123.f); // ^ format specifies type 'double' but the argument has type 'float' } ``` To address this issue, we teach FormatString about a few promotions that have always been around but that have never been exercised in the direction that FormatString checks for: * `char`, `unsigned char` -> `int`, `unsigned` * `half`, `float16`, `float` -> `double` This addresses issue https://github.com/llvm/llvm-project/issues/59824.
Loading
Please sign in to comment