forked from OSchip/llvm-project
[Sema] Formatting warnings should see through Objective-C message sends
This commit 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. rdar://23622446 Differential Revision: https://reviews.llvm.org/D25820 llvm-svn: 284961
This commit is contained in:
parent
bba497fb65
commit
d900714299
|
@ -4479,6 +4479,20 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,
|
|||
|
||||
return SLCT_NotALiteral;
|
||||
}
|
||||
case Stmt::ObjCMessageExprClass: {
|
||||
const auto *ME = cast<ObjCMessageExpr>(E);
|
||||
if (const auto *ND = ME->getMethodDecl()) {
|
||||
if (const auto *FA = ND->getAttr<FormatArgAttr>()) {
|
||||
unsigned ArgIndex = FA->getFormatIdx();
|
||||
const Expr *Arg = ME->getArg(ArgIndex - 1);
|
||||
return checkFormatStringExpr(
|
||||
S, Arg, Args, HasVAListArg, format_idx, firstDataArg, Type,
|
||||
CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset);
|
||||
}
|
||||
}
|
||||
|
||||
return SLCT_NotALiteral;
|
||||
}
|
||||
case Stmt::ObjCStringLiteralClass:
|
||||
case Stmt::StringLiteralClass: {
|
||||
const StringLiteral *StrE = nullptr;
|
||||
|
|
|
@ -264,3 +264,41 @@ void testObjCModifierFlags() {
|
|||
NSLog(@"%2$[tt]@ %1$[tt]@", @"Foo", @"Bar"); // no-warning
|
||||
NSLog(@"%2$[tt]@ %1$[tt]s", @"Foo", @"Bar"); // expected-warning {{object format flags cannot be used with 's' conversion specifier}}
|
||||
}
|
||||
|
||||
// rdar://23622446
|
||||
@interface RD23622446_Tester: NSObject
|
||||
|
||||
+ (void)stringWithFormat:(const char *)format, ... __attribute__((format(__printf__, 1, 2)));
|
||||
|
||||
@end
|
||||
|
||||
@implementation RD23622446_Tester
|
||||
|
||||
__attribute__ ((format_arg(1)))
|
||||
const char *rd23622446(const char *format) {
|
||||
return format;
|
||||
}
|
||||
|
||||
+ (void)stringWithFormat:(const char *)format, ... {
|
||||
return;
|
||||
}
|
||||
|
||||
- (const char *)test:(const char *)format __attribute__ ((format_arg(1))) {
|
||||
return format;
|
||||
}
|
||||
|
||||
- (NSString *)str:(NSString *)format __attribute__ ((format_arg(1))) {
|
||||
return format;
|
||||
}
|
||||
|
||||
- (void)foo {
|
||||
[RD23622446_Tester stringWithFormat:rd23622446("%u"), 1, 2]; // expected-warning {{data argument not used by format string}}
|
||||
[RD23622446_Tester stringWithFormat:[self test: "%u"], 1, 2]; // expected-warning {{data argument not used by format string}}
|
||||
[RD23622446_Tester stringWithFormat:[self test: "%s %s"], "name"]; // expected-warning {{more '%' conversions than data arguments}}
|
||||
NSLog([self str: @"%@ %@"], @"name"); // expected-warning {{more '%' conversions than data arguments}}
|
||||
[RD23622446_Tester stringWithFormat:rd23622446("%d"), 1]; // ok
|
||||
[RD23622446_Tester stringWithFormat:[self test: "%d %d"], 1, 2]; // ok
|
||||
NSLog([self str: @"%@"], @"string"); // ok
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue