Author: arphaman Date: Mon Oct 24 04:42:34 2016 New Revision: 284961 URL: http://llvm.org/viewvc/llvm-project?rev=284961&view=rev Log: [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 Modified: cfe/trunk/lib/Sema/SemaChecking.cpp cfe/trunk/test/SemaObjC/format-strings-objc.m Modified: cfe/trunk/lib/Sema/SemaChecking.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=284961&r1=284960&r2=284961&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaChecking.cpp (original) +++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Oct 24 04:42:34 2016 @@ -4479,6 +4479,20 @@ checkFormatStringExpr(Sema &S, const Exp 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; Modified: cfe/trunk/test/SemaObjC/format-strings-objc.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/format-strings-objc.m?rev=284961&r1=284960&r2=284961&view=diff ============================================================================== --- cfe/trunk/test/SemaObjC/format-strings-objc.m (original) +++ cfe/trunk/test/SemaObjC/format-strings-objc.m Mon Oct 24 04:42:34 2016 @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits