Skip to content

Commit 0ffba13

Browse files
author
git apple-llvm automerger
committed
Merge commit 'd378a0febc7e' from llvm.org/main into next
2 parents 45b7129 + d378a0f commit 0ffba13

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

clang/lib/Sema/SemaChecking.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8110,11 +8110,11 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,
81108110
// }
81118111
if (HasVAListArg) {
81128112
if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(VD)) {
8113-
if (const NamedDecl *ND = dyn_cast<NamedDecl>(PV->getDeclContext())) {
8113+
if (const Decl *D = dyn_cast<Decl>(PV->getDeclContext())) {
81148114
int PVIndex = PV->getFunctionScopeIndex() + 1;
8115-
for (const auto *PVFormat : ND->specific_attrs<FormatAttr>()) {
8115+
for (const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
81168116
// adjust for implicit parameter
8117-
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND))
8117+
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D))
81188118
if (MD->isInstance())
81198119
++PVIndex;
81208120
// We also check if the formats are compatible.

clang/test/Sema/format-strings.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs %s
2-
// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs -fno-signed-char %s
1+
// RUN: %clang_cc1 -fblocks -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs %s
2+
// RUN: %clang_cc1 -fblocks -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs -fno-signed-char %s
33

44
#include <stdarg.h>
55
#include <stddef.h>
@@ -741,3 +741,30 @@ void PR30481() {
741741
void test_printf_opaque_ptr(void *op) {
742742
printf("%s", op); // expected-warning{{format specifies type 'char *' but the argument has type 'void *'}}
743743
}
744+
745+
void test_block() {
746+
void __attribute__((__format__(__printf__, 1, 2))) (^printf_arg1)(
747+
const char *, ...) =
748+
^(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2))) {
749+
va_list ap;
750+
va_start(ap, fmt);
751+
vprintf(fmt, ap);
752+
va_end(ap);
753+
};
754+
755+
printf_arg1("%s string %i\n", "aaa", 123);
756+
printf_arg1("%s string\n", 123); // expected-warning{{format specifies type 'char *' but the argument has type 'int'}}
757+
758+
void __attribute__((__format__(__printf__, 2, 3))) (^printf_arg2)(
759+
const char *, const char *, ...) =
760+
^(const char *not_fmt, const char *fmt, ...)
761+
__attribute__((__format__(__printf__, 2, 3))) {
762+
va_list ap;
763+
va_start(ap, fmt);
764+
vprintf(not_fmt, ap); // expected-warning{{format string is not a string literal}}
765+
va_end(ap);
766+
};
767+
768+
printf_arg2("foo", "%s string %i\n", "aaa", 123);
769+
printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
770+
}

0 commit comments

Comments
 (0)