[PATCH] D112569: -Wformat-nonliteral should not trigger for format strings passed to blocks with __attribute__((format))
FĂ©lix Cloutier via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 26 14:16:33 PDT 2021
fcloutier updated this revision to Diff 382461.
fcloutier added a comment.
Thanks Artem for pointing out that I was completely misusing `getFunctionScopeIndex`. This should be better. I added a test that you can pick a non-1 value for the format parameter in blocks.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D112569/new/
https://reviews.llvm.org/D112569
Files:
clang/lib/Sema/SemaChecking.cpp
clang/test/Sema/format-strings.c
Index: clang/test/Sema/format-strings.c
===================================================================
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs %s
-// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs -fno-signed-char %s
+// RUN: %clang_cc1 -fblocks -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs %s
+// RUN: %clang_cc1 -fblocks -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs -fno-signed-char %s
#include <stdarg.h>
#include <stddef.h>
@@ -714,3 +714,30 @@
void test_printf_opaque_ptr(void *op) {
printf("%s", op); // expected-warning{{format specifies type 'char *' but the argument has type 'void *'}}
}
+
+void test_block() {
+ void __attribute__((__format__(__printf__, 1, 2))) (^printf_arg1)(
+ const char *, ...) =
+ ^(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2))) {
+ va_list ap;
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+ };
+
+ printf_arg1("%s string %i\n", "aaa", 123);
+ printf_arg1("%s string\n", 123); // expected-warning{{format specifies type 'char *' but the argument has type 'int'}}
+
+ void __attribute__((__format__(__printf__, 2, 3))) (^printf_arg2)(
+ const char *, const char *, ...) =
+ ^(const char *not_fmt, const char *fmt, ...)
+ __attribute__((__format__(__printf__, 2, 3))) {
+ va_list ap;
+ va_start(ap, fmt);
+ vprintf(not_fmt, ap); // expected-warning{{format string is not a string literal}}
+ va_end(ap);
+ };
+
+ printf_arg2("foo", "%s string %i\n", "aaa", 123);
+ printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
+}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -7780,13 +7780,13 @@
// }
if (HasVAListArg) {
if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(VD)) {
- if (const NamedDecl *ND = dyn_cast<NamedDecl>(PV->getDeclContext())) {
+ if (const Decl *D = dyn_cast<Decl>(PV->getDeclContext())) {
int PVIndex = PV->getFunctionScopeIndex() + 1;
- for (const auto *PVFormat : ND->specific_attrs<FormatAttr>()) {
- // adjust for implicit parameter
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND))
- if (MD->isInstance())
- ++PVIndex;
+ // adjust for implicit parameter
+ const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D);
+ if (MD && MD->isInstance())
+ ++PVIndex;
+ for (const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
// We also check if the formats are compatible.
// We can't pass a 'scanf' string to a 'printf' function.
if (PVIndex == PVFormat->getFormatIdx() &&
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D112569.382461.patch
Type: text/x-patch
Size: 3044 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211026/f104af06/attachment.bin>
More information about the cfe-commits
mailing list