Author: Félix Cloutier Date: 2021-10-28T20:25:00-07:00 New Revision: 6a5f7437720ea0fa184469584600c27a1a912a41
URL: https://github.com/llvm/llvm-project/commit/6a5f7437720ea0fa184469584600c27a1a912a41 DIFF: https://github.com/llvm/llvm-project/commit/6a5f7437720ea0fa184469584600c27a1a912a41.diff LOG: 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 Added: Modified: clang/lib/Sema/SemaDeclAttr.cpp clang/test/SemaObjC/format-arg-attribute.m Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 0c2b506d554b2..743b292d29759 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3388,6 +3388,12 @@ static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } Ty = getFunctionOrMethodResultType(D); + // replace instancetype with the class type + if (Ty.getTypePtr() == S.Context.getObjCInstanceTypeDecl()->getTypeForDecl()) + if (auto *OMD = dyn_cast<ObjCMethodDecl>(D)) + if (auto *Interface = OMD->getClassInterface()) + Ty = S.Context.getObjCObjectPointerType( + QualType(Interface->getTypeForDecl(), 0)); if (!isNSStringType(Ty, S.Context, /*AllowNSAttributedString=*/true) && !isCFStringType(Ty, S.Context) && (!Ty->isPointerType() || diff --git a/clang/test/SemaObjC/format-arg-attribute.m b/clang/test/SemaObjC/format-arg-attribute.m index ac81bdc21dc16..f137879880768 100644 --- a/clang/test/SemaObjC/format-arg-attribute.m +++ b/clang/test/SemaObjC/format-arg-attribute.m @@ -1,6 +1,14 @@ // RUN: %clang_cc1 -verify -fsyntax-only %s -@class NSString; +@interface NSString ++(instancetype)stringWithCString:(const char *)cstr __attribute__((format_arg(1))); ++(instancetype)stringWithString:(NSString *)cstr __attribute__((format_arg(1))); +@end + +@protocol MaybeString +-(instancetype)maybeString:(const char *)cstr __attribute__((format_arg(1))); // expected-error {{function does not return string type}} +@end + @class NSAttributedString; extern NSString *fa2 (const NSString *) __attribute__((format_arg(1))); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits