[PATCH] D112579: Allow non-variadic functions to be attributed with `__attribute__((format))`

FĂ©lix Cloutier via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 8 12:47:19 PDT 2022


fcloutier updated this revision to Diff 435302.
fcloutier added a comment.
Herald added a project: All.

Apologies the long delay: things happened and I was pulled away. I have some time to finish this change now. I recommend re-reading the discussion up to now since it's not _that_ long and it provides a lot of very useful context.

The new change addresses requests from the previous round. The most substantial changes are around how Clang detects that a format string is being forwarded to another format function. This is now expressed in terms of transitions from format argument passing styles, such that given the following 3 function archetypes:

  c
  void fixed(const char *, int) __attribute__((format(printf, 1, 2)));
  void variadic(const char *, ...) __attribute__((format(printf, 1, 2)));
  void valist(const char *, va_list) __attribute__((format(printf, 1, 0)));

there are no warnings for:

- a `variadic` function forwarding its format to a `valist` function
- a `valist` function forwarding its format to another `valist` function
- a `fixed` function forwarding its format to another `fixed` function (new)
- a `fixed` function forwarding its format to a `variadic` function (new)

In other words, for instance, `fixed` can call `variadic` in its implementation without a warning. Anything else, like forwarding the format of a `valist` function to a `fixed` function, is a diagnostic.

`fixed` to `fixed`/`variadic` transitions don't check that arguments have compatible types, but it conceivably could. This is a limitation of the current implementation. However, at this point, we don't think that this is a very worthwhile effort; this could change in the future if adoption of the `format` attribute on functions with a fixed signature ramps up.

I also added a number of tests to make sure that we still have reasonable warnings. One interesting edge case when using `__attribute__((format))` on functions with fixed parameters is that it's possible to come up with combinations that are impossible, for instance:

  c
  struct nontrivial { nontrivial(); ~nontrivial(); };
  void foo(const char *, nontrivial) __attribute__((format(printf, 1, 2)));

It's not a diagnostic to declare this function, however it is always a diagnostic to call it because no printf format specifier can format a `nontrivial` object. Ideally there would be a diagnostic on the declaration, but I think that it's sufficient as it is.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112579/new/

https://reviews.llvm.org/D112579

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/Sema/attr-format.c
  clang/test/Sema/format-strings.c
  clang/test/SemaCXX/attr-format.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D112579.435302.patch
Type: text/x-patch
Size: 44722 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220608/162de9fb/attachment-0001.bin>


More information about the cfe-commits mailing list