[PATCH] D112670: __attribute__((format_arg(__NSString__, N))) does not support instancetype in NSString interface

FĂ©lix Cloutier via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 27 15:32:21 PDT 2021


fcloutier created this revision.
fcloutier added reviewers: doug.gregor, dcoughlin, rsmith, 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.

It has come to my attention that _inside the interface of `NSString_`, using `__attribute__((format_arg(__NSString__, N)))` does not work for a method that returns `instancetype`. This is a pretty specific problem because not a lot of people define `NSString`. Thankfully, the fix isn't very difficult: if checking an Objective-C method definition, and it returns `instancetype`, we also check if the class being defined is `NSString`.

rdar://84729746


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D112670

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
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -verify -fsyntax-only %s
 
- at class NSString;
+ at interface NSString
++(instancetype)stringWithCString:(const char *)cstr __attribute__((format_arg(1)));
+ at end
+
 @class NSAttributedString;
 
 extern NSString *fa2 (const NSString *) __attribute__((format_arg(1)));
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -156,26 +156,39 @@
   return false;
 }
 
-static inline bool isNSStringType(QualType T, ASTContext &Ctx,
-                                  bool AllowNSAttributedString = false) {
-  const auto *PT = T->getAs<ObjCObjectPointerType>();
-  if (!PT)
-    return false;
-
-  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
+static inline bool isNSStringInterface(ASTContext &Ctx, ObjCInterfaceDecl *Cls, bool AllowNSAttributedString = false) {
   if (!Cls)
     return false;
 
-  IdentifierInfo* ClsName = Cls->getIdentifier();
+  IdentifierInfo *ClsName = Cls->getIdentifier();
 
-  if (AllowNSAttributedString &&
-      ClsName == &Ctx.Idents.get("NSAttributedString"))
-    return true;
+  if (ClsName == &Ctx.Idents.get("NSAttributedString"))
+    return AllowNSAttributedString;
   // FIXME: Should we walk the chain of classes?
   return ClsName == &Ctx.Idents.get("NSString") ||
          ClsName == &Ctx.Idents.get("NSMutableString");
 }
 
+static inline bool isNSStringType(QualType T, ASTContext &Ctx,
+                                  bool AllowNSAttributedString = false) {
+  const auto *PT = T->getAs<ObjCObjectPointerType>();
+  if (!PT)
+    return false;
+  
+  return isNSStringInterface(Ctx, PT->getObjectType()->getInterface(), AllowNSAttributedString);
+}
+
+static inline bool isInstancetypeNSStringType(ASTContext &Ctx, QualType T, Decl *D, bool AllowNSAttributedString = false) {
+  if (T.getTypePtr() != Ctx.getObjCInstanceTypeDecl()->getTypeForDecl())
+    return false;
+  
+  auto *OMD = dyn_cast<ObjCMethodDecl>(D);
+  if (!OMD)
+    return false;
+  
+  return isNSStringInterface(Ctx, OMD->getClassInterface(), AllowNSAttributedString);
+}
+
 static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
   const auto *PT = T->getAs<PointerType>();
   if (!PT)
@@ -3390,6 +3403,7 @@
   Ty = getFunctionOrMethodResultType(D);
   if (!isNSStringType(Ty, S.Context, /*AllowNSAttributedString=*/true) &&
       !isCFStringType(Ty, S.Context) &&
+      !isInstancetypeNSStringType(S.Context, Ty, D) &&
       (!Ty->isPointerType() ||
        !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
     S.Diag(AL.getLoc(), diag::err_format_attribute_result_not)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D112670.382819.patch
Type: text/x-patch
Size: 2903 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211027/87b66e75/attachment.bin>


More information about the cfe-commits mailing list