[PATCH] D113636: format_arg attribute does not support nullable instancetype return type

Félix Cloutier via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 10 18:10:33 PST 2021


fcloutier created this revision.
fcloutier added reviewers: NoQ, ahatanak.
fcloutier added a project: clang.
Herald added a reviewer: aaron.ballman.
fcloutier requested review of this revision.
Herald added a subscriber: cfe-commits.

Following up with D112670 <https://reviews.llvm.org/D112670>, it appears that the original fix was insufficient: it's not possible to use `__attribute__((format_arg))` on methods that return `instancetype` in `NSString` when `instancetype` is sugared, as this breaks pointer equality. Although this is only possible in limited scenarios because `instancetype` is a contextual keyword, it can (crucially) be combined with nullability qualifiers.

rdar://85278860


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D113636

Files:
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/SemaObjC/format-arg-attribute.m


Index: clang/test/SemaObjC/format-arg-attribute.m
===================================================================
--- clang/test/SemaObjC/format-arg-attribute.m
+++ clang/test/SemaObjC/format-arg-attribute.m
@@ -2,7 +2,10 @@
 
 @interface NSString
 +(instancetype)stringWithCString:(const char *)cstr __attribute__((format_arg(1)));
-+(instancetype)stringWithString:(NSString *)cstr __attribute__((format_arg(1)));
+-(instancetype)initWithString:(NSString *)str __attribute__((format_arg(1)));
+
++(instancetype _Nonnull)nonNullableString:(NSString *)str __attribute__((format_arg(1)));
++(instancetype _Nullable)nullableString:(NSString *)str __attribute__((format_arg(1)));
 @end
 
 @protocol MaybeString
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -3389,7 +3389,8 @@
   }
   Ty = getFunctionOrMethodResultType(D);
   // replace instancetype with the class type
-  if (Ty.getTypePtr() == S.Context.getObjCInstanceTypeDecl()->getTypeForDecl())
+  auto Instancetype = S.Context.getObjCInstanceTypeDecl()->getTypeForDecl();
+  if (Ty->getAs<TypedefType>() == Instancetype)
     if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
       if (auto *Interface = OMD->getClassInterface())
         Ty = S.Context.getObjCObjectPointerType(


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113636.386388.patch
Type: text/x-patch
Size: 1369 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211111/53a2f29c/attachment.bin>


More information about the cfe-commits mailing list