[all-commits] [llvm/llvm-project] 04e617: [Sema] tolerate more promotion matches in format s...

apple-fcloutier via All-commits all-commits at lists.llvm.org
Fri Aug 25 10:14:35 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 04e6178ae932c9a1d939dcfe3ef1189f4bbb21aa
      https://github.com/llvm/llvm-project/commit/04e6178ae932c9a1d939dcfe3ef1189f4bbb21aa
  Author: FĂ©lix Cloutier <fcloutier at apple.com>
  Date:   2023-08-25 (Fri, 25 Aug 2023)

  Changed paths:
    M clang/docs/ReleaseNotes.rst
    M clang/lib/AST/FormatString.cpp
    M clang/test/Sema/attr-format.c
    M clang/test/SemaCXX/attr-format.cpp
    A clang/test/SemaCXX/format-strings-scanf.cpp

  Log Message:
  -----------
  [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.




More information about the All-commits mailing list