Author: hans Date: Fri Aug 14 17:43:37 2015 New Revision: 245116 URL: http://llvm.org/viewvc/llvm-project?rev=245116&view=rev Log: Merging r244193: ------------------------------------------------------------------------ r244193 | alexdenisov | 2015-08-05 21:51:14 -0700 (Wed, 05 Aug 2015) | 3 lines
[ObjC] Circular containers: add support of subclasses ------------------------------------------------------------------------ Modified: cfe/branches/release_37/ (props changed) cfe/branches/release_37/include/clang/AST/NSAPI.h cfe/branches/release_37/include/clang/Basic/DiagnosticSemaKinds.td cfe/branches/release_37/include/clang/Sema/Sema.h cfe/branches/release_37/lib/AST/NSAPI.cpp cfe/branches/release_37/lib/Sema/SemaChecking.cpp cfe/branches/release_37/test/SemaObjC/circular-container.m Propchange: cfe/branches/release_37/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Fri Aug 14 17:43:37 2015 @@ -1,4 +1,4 @@ /cfe/branches/type-system-rewrite:134693-134817 -/cfe/trunk:242244,242285,242293,242297,242313,242382,242422,242499,242574,242600,242660,242662,242667,242678,242766,242854,242905,242973,243018,243048,243085,243098,243101,243105,243133,243144,243153,243196,243206,243277,243280,243285,243289,243343,243417,243463,243538,243594,243642-243644,243851,243945-243950,243964,244000,244468,244719,244794 +/cfe/trunk:242244,242285,242293,242297,242313,242382,242422,242499,242574,242600,242660,242662,242667,242678,242766,242854,242905,242973,243018,243048,243085,243098,243101,243105,243133,243144,243153,243196,243206,243277,243280,243285,243289,243343,243417,243463,243538,243594,243642-243644,243851,243945-243950,243964,244000,244193,244468,244719,244794 /cfe/trunk/test:170344 /cfe/trunk/test/SemaTemplate:126920 Modified: cfe/branches/release_37/include/clang/AST/NSAPI.h URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_37/include/clang/AST/NSAPI.h?rev=245116&r1=245115&r2=245116&view=diff ============================================================================== --- cfe/branches/release_37/include/clang/AST/NSAPI.h (original) +++ cfe/branches/release_37/include/clang/AST/NSAPI.h Fri Aug 14 17:43:37 2015 @@ -16,6 +16,7 @@ namespace clang { class ASTContext; + class ObjCInterfaceDecl; class QualType; class Expr; @@ -35,11 +36,10 @@ public: ClassId_NSMutableDictionary, ClassId_NSNumber, ClassId_NSMutableSet, - ClassId_NSCountedSet, ClassId_NSMutableOrderedSet, ClassId_NSValue }; - static const unsigned NumClassIds = 11; + static const unsigned NumClassIds = 10; enum NSStringMethodKind { NSStr_stringWithString, @@ -220,6 +220,10 @@ public: /// \brief Returns \c true if \p Id is currently defined as a macro. bool isMacroDefined(StringRef Id) const; + /// \brief Returns \c true if \p InterfaceDecl is subclass of \p NSClassKind + bool isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl, + NSClassIdKindKind NSClassKind) const; + private: bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const; bool isObjCEnumerator(const Expr *E, Modified: cfe/branches/release_37/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_37/include/clang/Basic/DiagnosticSemaKinds.td?rev=245116&r1=245115&r2=245116&view=diff ============================================================================== --- cfe/branches/release_37/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/branches/release_37/include/clang/Basic/DiagnosticSemaKinds.td Fri Aug 14 17:43:37 2015 @@ -5358,7 +5358,7 @@ def err_objc_object_catch : Error< def err_incomplete_type_objc_at_encode : Error< "'@encode' of incomplete type %0">; def warn_objc_circular_container : Warning< - "adding '%0' to '%0' might cause circular dependency in container">, + "adding '%0' to '%1' might cause circular dependency in container">, InGroup<DiagGroup<"objc-circular-container">>; def note_objc_circular_container_declared_here : Note<"'%0' declared here">; Modified: cfe/branches/release_37/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_37/include/clang/Sema/Sema.h?rev=245116&r1=245115&r2=245116&view=diff ============================================================================== --- cfe/branches/release_37/include/clang/Sema/Sema.h (original) +++ cfe/branches/release_37/include/clang/Sema/Sema.h Fri Aug 14 17:43:37 2015 @@ -729,27 +729,12 @@ public: /// \brief The declaration of the Objective-C NSArray class. ObjCInterfaceDecl *NSArrayDecl; - /// \brief Pointer to NSMutableArray type (NSMutableArray *). - QualType NSMutableArrayPointer; - /// \brief The declaration of the arrayWithObjects:count: method. ObjCMethodDecl *ArrayWithObjectsMethod; /// \brief The declaration of the Objective-C NSDictionary class. ObjCInterfaceDecl *NSDictionaryDecl; - /// \brief Pointer to NSMutableDictionary type (NSMutableDictionary *). - QualType NSMutableDictionaryPointer; - - /// \brief Pointer to NSMutableSet type (NSMutableSet *). - QualType NSMutableSetPointer; - - /// \brief Pointer to NSCountedSet type (NSCountedSet *). - QualType NSCountedSetPointer; - - /// \brief Pointer to NSMutableOrderedSet type (NSMutableOrderedSet *). - QualType NSMutableOrderedSetPointer; - /// \brief The declaration of the dictionaryWithObjects:forKeys:count: method. ObjCMethodDecl *DictionaryWithObjectsMethod; Modified: cfe/branches/release_37/lib/AST/NSAPI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_37/lib/AST/NSAPI.cpp?rev=245116&r1=245115&r2=245116&view=diff ============================================================================== --- cfe/branches/release_37/lib/AST/NSAPI.cpp (original) +++ cfe/branches/release_37/lib/AST/NSAPI.cpp Fri Aug 14 17:43:37 2015 @@ -9,6 +9,7 @@ #include "clang/AST/NSAPI.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "llvm/ADT/StringSwitch.h" @@ -29,7 +30,6 @@ IdentifierInfo *NSAPI::getNSClassId(NSCl "NSMutableDictionary", "NSNumber", "NSMutableSet", - "NSCountedSet", "NSMutableOrderedSet", "NSValue" }; @@ -511,6 +511,26 @@ bool NSAPI::isMacroDefined(StringRef Id) return Ctx.Idents.get(Id).hasMacroDefinition(); } +bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl, + NSClassIdKindKind NSClassKind) const { + if (!InterfaceDecl) { + return false; + } + + IdentifierInfo *NSClassID = getNSClassId(NSClassKind); + + bool IsSubclass = false; + do { + IsSubclass = NSClassID == InterfaceDecl->getIdentifier(); + + if (IsSubclass) { + break; + } + } while ((InterfaceDecl = InterfaceDecl->getSuperClass())); + + return IsSubclass; +} + bool NSAPI::isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const { if (!Ctx.getLangOpts().ObjC1) Modified: cfe/branches/release_37/lib/Sema/SemaChecking.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_37/lib/Sema/SemaChecking.cpp?rev=245116&r1=245115&r2=245116&view=diff ============================================================================== --- cfe/branches/release_37/lib/Sema/SemaChecking.cpp (original) +++ cfe/branches/release_37/lib/Sema/SemaChecking.cpp Fri Aug 14 17:43:37 2015 @@ -8727,23 +8727,10 @@ static bool isSetterLikeSelector(Selecto static Optional<int> GetNSMutableArrayArgumentIndex(Sema &S, ObjCMessageExpr *Message) { - if (S.NSMutableArrayPointer.isNull()) { - IdentifierInfo *NSMutableArrayId = - S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSMutableArray); - NamedDecl *IF = S.LookupSingleName(S.TUScope, NSMutableArrayId, - Message->getLocStart(), - Sema::LookupOrdinaryName); - ObjCInterfaceDecl *InterfaceDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF); - if (!InterfaceDecl) { - return None; - } - QualType NSMutableArrayObject = - S.Context.getObjCInterfaceType(InterfaceDecl); - S.NSMutableArrayPointer = - S.Context.getObjCObjectPointerType(NSMutableArrayObject); - } - - if (S.NSMutableArrayPointer != Message->getReceiverType()) { + bool IsMutableArray = S.NSAPIObj->isSubclassOfNSClass( + Message->getReceiverInterface(), + NSAPI::ClassId_NSMutableArray); + if (!IsMutableArray) { return None; } @@ -8775,24 +8762,10 @@ static Optional<int> GetNSMutableArrayAr static Optional<int> GetNSMutableDictionaryArgumentIndex(Sema &S, ObjCMessageExpr *Message) { - - if (S.NSMutableDictionaryPointer.isNull()) { - IdentifierInfo *NSMutableDictionaryId = - S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSMutableDictionary); - NamedDecl *IF = S.LookupSingleName(S.TUScope, NSMutableDictionaryId, - Message->getLocStart(), - Sema::LookupOrdinaryName); - ObjCInterfaceDecl *InterfaceDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF); - if (!InterfaceDecl) { - return None; - } - QualType NSMutableDictionaryObject = - S.Context.getObjCInterfaceType(InterfaceDecl); - S.NSMutableDictionaryPointer = - S.Context.getObjCObjectPointerType(NSMutableDictionaryObject); - } - - if (S.NSMutableDictionaryPointer != Message->getReceiverType()) { + bool IsMutableDictionary = S.NSAPIObj->isSubclassOfNSClass( + Message->getReceiverInterface(), + NSAPI::ClassId_NSMutableDictionary); + if (!IsMutableDictionary) { return None; } @@ -8820,63 +8793,14 @@ Optional<int> GetNSMutableDictionaryArgu } static Optional<int> GetNSSetArgumentIndex(Sema &S, ObjCMessageExpr *Message) { - - ObjCInterfaceDecl *InterfaceDecl; - if (S.NSMutableSetPointer.isNull()) { - IdentifierInfo *NSMutableSetId = - S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSMutableSet); - NamedDecl *IF = S.LookupSingleName(S.TUScope, NSMutableSetId, - Message->getLocStart(), - Sema::LookupOrdinaryName); - InterfaceDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF); - if (InterfaceDecl) { - QualType NSMutableSetObject = - S.Context.getObjCInterfaceType(InterfaceDecl); - S.NSMutableSetPointer = - S.Context.getObjCObjectPointerType(NSMutableSetObject); - } - } - - if (S.NSCountedSetPointer.isNull()) { - IdentifierInfo *NSCountedSetId = - S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSCountedSet); - NamedDecl *IF = S.LookupSingleName(S.TUScope, NSCountedSetId, - Message->getLocStart(), - Sema::LookupOrdinaryName); - InterfaceDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF); - if (InterfaceDecl) { - QualType NSCountedSetObject = - S.Context.getObjCInterfaceType(InterfaceDecl); - S.NSCountedSetPointer = - S.Context.getObjCObjectPointerType(NSCountedSetObject); - } - } - - if (S.NSMutableOrderedSetPointer.isNull()) { - IdentifierInfo *NSOrderedSetId = - S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSMutableOrderedSet); - NamedDecl *IF = S.LookupSingleName(S.TUScope, NSOrderedSetId, - Message->getLocStart(), - Sema::LookupOrdinaryName); - InterfaceDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF); - if (InterfaceDecl) { - QualType NSOrderedSetObject = - S.Context.getObjCInterfaceType(InterfaceDecl); - S.NSMutableOrderedSetPointer = - S.Context.getObjCObjectPointerType(NSOrderedSetObject); - } - } - - QualType ReceiverType = Message->getReceiverType(); - - bool IsMutableSet = !S.NSMutableSetPointer.isNull() && - ReceiverType == S.NSMutableSetPointer; - bool IsMutableOrderedSet = !S.NSMutableOrderedSetPointer.isNull() && - ReceiverType == S.NSMutableOrderedSetPointer; - bool IsCountedSet = !S.NSCountedSetPointer.isNull() && - ReceiverType == S.NSCountedSetPointer; - - if (!IsMutableSet && !IsMutableOrderedSet && !IsCountedSet) { + bool IsMutableSet = S.NSAPIObj->isSubclassOfNSClass( + Message->getReceiverInterface(), + NSAPI::ClassId_NSMutableSet); + + bool IsMutableOrderedSet = S.NSAPIObj->isSubclassOfNSClass( + Message->getReceiverInterface(), + NSAPI::ClassId_NSMutableOrderedSet); + if (!IsMutableSet && !IsMutableOrderedSet) { return None; } @@ -8917,38 +8841,51 @@ void Sema::CheckObjCCircularContainer(Ob int ArgIndex = *ArgOpt; - Expr *Receiver = Message->getInstanceReceiver()->IgnoreImpCasts(); - if (OpaqueValueExpr *OE = dyn_cast<OpaqueValueExpr>(Receiver)) { - Receiver = OE->getSourceExpr()->IgnoreImpCasts(); - } - Expr *Arg = Message->getArg(ArgIndex)->IgnoreImpCasts(); if (OpaqueValueExpr *OE = dyn_cast<OpaqueValueExpr>(Arg)) { Arg = OE->getSourceExpr()->IgnoreImpCasts(); } - if (DeclRefExpr *ReceiverRE = dyn_cast<DeclRefExpr>(Receiver)) { + if (Message->getReceiverKind() == ObjCMessageExpr::SuperInstance) { if (DeclRefExpr *ArgRE = dyn_cast<DeclRefExpr>(Arg)) { - if (ReceiverRE->getDecl() == ArgRE->getDecl()) { - ValueDecl *Decl = ReceiverRE->getDecl(); + if (ArgRE->isObjCSelfExpr()) { Diag(Message->getSourceRange().getBegin(), diag::warn_objc_circular_container) - << Decl->getName(); - Diag(Decl->getLocation(), - diag::note_objc_circular_container_declared_here) - << Decl->getName(); + << ArgRE->getDecl()->getName() << StringRef("super"); } } - } else if (ObjCIvarRefExpr *IvarRE = dyn_cast<ObjCIvarRefExpr>(Receiver)) { - if (ObjCIvarRefExpr *IvarArgRE = dyn_cast<ObjCIvarRefExpr>(Arg)) { - if (IvarRE->getDecl() == IvarArgRE->getDecl()) { - ObjCIvarDecl *Decl = IvarRE->getDecl(); - Diag(Message->getSourceRange().getBegin(), - diag::warn_objc_circular_container) - << Decl->getName(); - Diag(Decl->getLocation(), - diag::note_objc_circular_container_declared_here) - << Decl->getName(); + } else { + Expr *Receiver = Message->getInstanceReceiver()->IgnoreImpCasts(); + + if (OpaqueValueExpr *OE = dyn_cast<OpaqueValueExpr>(Receiver)) { + Receiver = OE->getSourceExpr()->IgnoreImpCasts(); + } + + if (DeclRefExpr *ReceiverRE = dyn_cast<DeclRefExpr>(Receiver)) { + if (DeclRefExpr *ArgRE = dyn_cast<DeclRefExpr>(Arg)) { + if (ReceiverRE->getDecl() == ArgRE->getDecl()) { + ValueDecl *Decl = ReceiverRE->getDecl(); + Diag(Message->getSourceRange().getBegin(), + diag::warn_objc_circular_container) + << Decl->getName() << Decl->getName(); + if (!ArgRE->isObjCSelfExpr()) { + Diag(Decl->getLocation(), + diag::note_objc_circular_container_declared_here) + << Decl->getName(); + } + } + } + } else if (ObjCIvarRefExpr *IvarRE = dyn_cast<ObjCIvarRefExpr>(Receiver)) { + if (ObjCIvarRefExpr *IvarArgRE = dyn_cast<ObjCIvarRefExpr>(Arg)) { + if (IvarRE->getDecl() == IvarArgRE->getDecl()) { + ObjCIvarDecl *Decl = IvarRE->getDecl(); + Diag(Message->getSourceRange().getBegin(), + diag::warn_objc_circular_container) + << Decl->getName() << Decl->getName(); + Diag(Decl->getLocation(), + diag::note_objc_circular_container_declared_here) + << Decl->getName(); + } } } } Modified: cfe/branches/release_37/test/SemaObjC/circular-container.m URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_37/test/SemaObjC/circular-container.m?rev=245116&r1=245115&r2=245116&view=diff ============================================================================== --- cfe/branches/release_37/test/SemaObjC/circular-container.m (original) +++ cfe/branches/release_37/test/SemaObjC/circular-container.m Fri Aug 14 17:43:37 2015 @@ -144,3 +144,64 @@ void checkNSMutableOrderedSet() { [s replaceObjectAtIndex:0 withObject:s]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} } +// Test subclassing + +@interface FootableSet : NSMutableSet +@end + +@implementation FootableSet +- (void)meth { + [super addObject:self]; // expected-warning {{adding 'self' to 'super' might cause circular dependency in container}} + [super addObject:nil]; // no-warning + [self addObject:self]; // expected-warning {{adding 'self' to 'self' might cause circular dependency in container}} +} +@end + +@interface FootableArray : NSMutableArray +@end + +@implementation FootableArray +- (void)meth { + [super addObject:self]; // expected-warning {{adding 'self' to 'super' might cause circular dependency in container}} + [super addObject:nil]; // no-warning + [self addObject:self]; // expected-warning {{adding 'self' to 'self' might cause circular dependency in container}} +} +@end + +@interface FootableDictionary : NSMutableDictionary +@end + +@implementation FootableDictionary +- (void)meth { + [super setObject:self forKey:@"key"]; // expected-warning {{adding 'self' to 'super' might cause circular dependency in container}} + [super setObject:nil forKey:@"key"]; // no-warning + [self setObject:self forKey:@"key"]; // expected-warning {{adding 'self' to 'self' might cause circular dependency in container}} +} +@end + + +void subclassingNSMutableArray() { + FootableArray *a = nil; // expected-note 5 {{'a' declared here}} 5 + + [a addObject:a]; // expected-warning {{adding 'a' to 'a' might cause circular dependency in container}} + [a insertObject:a atIndex:0]; // expected-warning {{adding 'a' to 'a' might cause circular dependency in container}} + [a replaceObjectAtIndex:0 withObject:a]; // expected-warning {{adding 'a' to 'a' might cause circular dependency in container}} + [a setObject:a atIndexedSubscript:0]; // expected-warning {{adding 'a' to 'a' might cause circular dependency in container}} + a[0] = a; // expected-warning {{adding 'a' to 'a' might cause circular dependency in container}} +} + +void subclassingNSMutableDictionary() { + FootableDictionary *d = nil; // expected-note 4 {{'d' declared here}} + + [d setObject:d forKey:@"key"]; // expected-warning {{adding 'd' to 'd' might cause circular dependency in container}} + [d setObject:d forKeyedSubscript:@"key"]; // expected-warning {{adding 'd' to 'd' might cause circular dependency in container}} + [d setValue:d forKey:@"key"]; // expected-warning {{adding 'd' to 'd' might cause circular dependency in container}} + d[@"key"] = d; // expected-warning {{adding 'd' to 'd' might cause circular dependency in container}} +} + +void subclassingNSMutableSet() { + FootableSet *s = nil; // expected-note {{'s' declared here}} + + [s addObject:s]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} +} + _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits