This patch improves the '-Wformat' warnings by ensuring that the formatting checker can see through Objective-C message sends when we are calling an Objective-C method with an appropriate format_arg attribute.
Actually, looking more deeply, it's possible this is a bug in the Apple SDK:
@interface NSBundle - (NSString *)localizedStringForKey:(NSString *)key value:(nullable NSString *)value table:(nullable NSString *)tableName __attribute__((format_arg(1))); @end
Since format_arg(X) is 1-based, and value is the format param here, I wonder if this shouldn't be __attribute__((format_arg(2)).
That does look like a bug in the SDK, to me.
OK. I'll file a Radar bug upstream; in the meantime, this means since this diff landed in 2016, clang has been raising -Wformat-extra-args when compiling any code which passes the result of -[NSBundle localizedStringForKey:value:table:] to +[NSString stringWithFormat:] and friends (which is a fairly common operation—any localized string with an argument will do this).
I assume Apple will fix this in the SDK the next time they integrate their fork of clang from master.
I filed rdar://38143508 to track this.
The fix won't be easy; I think __attribute__((format_arg(X))) isn't enough to capture how -[NSBundle localizedStringForKey:value:table:] works:
- __attribute__((format_arg(X))) doesn't support multiple format arguments, and it appears to ignore everything but the last such declaration:
- NSLocalizedString() and friends pass @"" as the value argument, which raises -Wformat-zero-length if we tag it as a format argument:
test.m:21:12: error: format string is empty [-Werror,-Wformat-zero-length] @"", ~^~ test.m:14:46: note: expanded from macro 'NSLocalizedStringWithDefaultValue' [bundle localizedStringForKey:(key) value:(val) table:(tbl)] ^~~ 1 error generated.
This means we'll either need a new attribute which allows a zero-length format string, or a way to change format_arg to understand this "argument with default value" semantic.