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(
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(
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits