Skip to content

Commit 98f298e

Browse files
format_arg attribute should allow instancetype in NSString definition
- [[format_arg(N)]] tells Clang that a method returns a format string with specifiers equivalent to those passed in the string at argument #N. It obviously requires the argument and the return type to be strings both. - `instancetype` is a special return type available in Objective-C class definitions that Clang expands to the most-derived statically known type on use. - In Objective-C mode, NSString is allowed in lieu of a C string, both as input and output. However, _in the definition of NSString_, Clang rejects format_arg on methods that return NSString. This PR addresses this issue by substituting `instancetype` with the enclosing definition's type during the validation of `format_arg`. Reviewed By: ahatanak Differential Revision: https://reviews.llvm.org/D112670 Radar-Id: rdar://84729746
1 parent 1a0ab67 commit 98f298e

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3397,6 +3397,12 @@ static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
33973397
return;
33983398
}
33993399
Ty = getFunctionOrMethodResultType(D);
3400+
// replace instancetype with the class type
3401+
if (Ty.getTypePtr() == S.Context.getObjCInstanceTypeDecl()->getTypeForDecl())
3402+
if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3403+
if (auto *Interface = OMD->getClassInterface())
3404+
Ty = S.Context.getObjCObjectPointerType(
3405+
QualType(Interface->getTypeForDecl(), 0));
34003406
if (!isNSStringType(Ty, S.Context, /*AllowNSAttributedString=*/true) &&
34013407
!isCFStringType(Ty, S.Context) &&
34023408
(!Ty->isPointerType() ||

clang/test/SemaObjC/format-arg-attribute.m

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
// RUN: %clang_cc1 -verify -fsyntax-only %s
22

3-
@class NSString;
3+
@interface NSString
4+
+(instancetype)stringWithCString:(const char *)cstr __attribute__((format_arg(1)));
5+
+(instancetype)stringWithString:(NSString *)cstr __attribute__((format_arg(1)));
6+
@end
7+
8+
@protocol MaybeString
9+
-(instancetype)maybeString:(const char *)cstr __attribute__((format_arg(1))); // expected-error {{function does not return string type}}
10+
@end
11+
412
@class NSAttributedString;
513

614
extern NSString *fa2 (const NSString *) __attribute__((format_arg(1)));

0 commit comments

Comments
 (0)