The checker that implements -Wformat-nonliteral does not understand __attribute__((format)) on blocks in the same way that it understands it on functions. This works just fine (assuming #define __printflike(A, B) __attribute__((format(printf, A, B)))):
void printfblock(const char *fmt, ...) __printflike(1, 2) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); } void foo(void) { printfblock("%s %i\n", "hello", 1); }
However, this incorrectly triggers -Wformat-nonliteral:
void foo(void) { void (^printfblock)(const char *fmt, ...) __printflike(1, 2) = ^(const char *fmt, ...) __printflike(1, 2) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); // warning: format string is not a string literal [-Wformat-nonliteral] va_end(ap); }; printfblock("%s %i\n", "hello", 1); }
This patch updates checkFormatStringExpr so that it can look through BlockDecls and find out which parameter is identified as a format string.
rdar://84603673
This code now says that all block parameters have index 1 because blocks aren't named(?) I don't think this is correct. I also don't see why this cast is necessary in the first place. The only place where ND is used is the cast into MD which might as well be performed on D directly.