From 08ee284dc08719fa071ec112f4d1ce9cfb646fba Mon Sep 17 00:00:00 2001 From: Alex Lorenz <arphaman@gmail.com> Date: Wed, 23 May 2018 00:52:20 +0000 Subject: [PATCH] [AST][ObjC] Print implicit property expression that only has a setter without crashing rdar://40447209 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@333046 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/IdentifierTable.h | 3 +++ lib/AST/StmtPrinter.cpp | 10 +++++++--- lib/Basic/IdentifierTable.cpp | 6 ++++++ test/Misc/ast-print-objectivec.m | 10 ++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index 10a0251453..9a33873518 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -825,6 +825,9 @@ public: static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name); + + /// Return the property name for the given setter selector. + static std::string getPropertyNameFromSetterSelector(Selector Sel); }; /// DeclarationNameExtra - Common base of the MultiKeywordSelector, diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index dc6cc16071..38ec6632e7 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -1406,9 +1406,13 @@ void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { OS << Node->getClassReceiver()->getName() << "."; } - if (Node->isImplicitProperty()) - Node->getImplicitPropertyGetter()->getSelector().print(OS); - else + if (Node->isImplicitProperty()) { + if (const auto *Getter = Node->getImplicitPropertyGetter()) + Getter->getSelector().print(OS); + else + OS << SelectorTable::getPropertyNameFromSetterSelector( + Node->getImplicitPropertySetter()->getSelector()); + } else OS << Node->getExplicitProperty()->getName(); } diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp index ec9ca7616c..37703ca776 100644 --- a/lib/Basic/IdentifierTable.cpp +++ b/lib/Basic/IdentifierTable.cpp @@ -645,6 +645,12 @@ SelectorTable::constructSetterSelector(IdentifierTable &Idents, return SelTable.getUnarySelector(SetterName); } +std::string SelectorTable::getPropertyNameFromSetterSelector(Selector Sel) { + StringRef Name = Sel.getNameForSlot(0); + assert(Name.startswith("set") && "invalid setter name"); + return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str(); +} + size_t SelectorTable::getTotalMemory() const { SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl); return SelTabImpl.Allocator.getTotalMemory(); diff --git a/test/Misc/ast-print-objectivec.m b/test/Misc/ast-print-objectivec.m index eb1b469610..05a0a5d4aa 100644 --- a/test/Misc/ast-print-objectivec.m +++ b/test/Misc/ast-print-objectivec.m @@ -50,3 +50,13 @@ struct __attribute__((objc_bridge_related(C1,,))) S1; // CHECK: @class C1; // CHECK: struct __attribute__((objc_bridge_related(C1, , ))) S1; + +@interface ImplicitPropertyWithSetterOnly + +- (void)setX:(int)x; + +@end + +void printImplicitPropertyWithSetterOnly(ImplicitPropertyWithSetterOnly *x) { + x.x = 313; // CHECK: x.x = 313; +} -- 2.40.0