[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