diff options
author | Alex Denisov <1101.debian@gmail.com> | 2015-03-04 17:55:52 +0000 |
---|---|---|
committer | Alex Denisov <1101.debian@gmail.com> | 2015-03-04 17:55:52 +0000 |
commit | e1d882c726b53eebe4dbece9fdf7fb8dc6469f72 (patch) | |
tree | 60507712962fd8ed3cca070487229c64a1052884 /clang/lib/AST/NSAPI.cpp | |
parent | 4d9347993bbaaf9278df52d14e71e460a4afbd9f (diff) | |
download | bcm5719-llvm-e1d882c726b53eebe4dbece9fdf7fb8dc6469f72.tar.gz bcm5719-llvm-e1d882c726b53eebe4dbece9fdf7fb8dc6469f72.zip |
New ObjC warning: circular containers.
This commit adds new warning to prevent user from creating 'circular containers'.
Mutable collections from NSFoundation allows user to add collection to itself, e.g.:
NSMutableArray *a = [NSMutableArray new];
[a addObject:a];
The code above leads to really weird behaviour (crashes, 'endless' recursion) and
retain cycles (collection retains itself) if ARC enabled.
Patch checks the following collections:
- NSMutableArray,
- NSMutableDictionary,
- NSMutableSet,
- NSMutableOrderedSet,
- NSCountedSet.
llvm-svn: 231265
Diffstat (limited to 'clang/lib/AST/NSAPI.cpp')
-rw-r--r-- | clang/lib/AST/NSAPI.cpp | 97 |
1 files changed, 96 insertions, 1 deletions
diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp index 3dc750a8178..033a87b8ae2 100644 --- a/clang/lib/AST/NSAPI.cpp +++ b/clang/lib/AST/NSAPI.cpp @@ -27,7 +27,10 @@ IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const { "NSMutableArray", "NSDictionary", "NSMutableDictionary", - "NSNumber" + "NSNumber", + "NSMutableSet", + "NSCountedSet", + "NSMutableOrderedSet" }; if (!ClassIds[K]) @@ -124,6 +127,25 @@ Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const { Sel = Ctx.Selectors.getSelector(2, KeyIdents); break; } + case NSMutableArr_addObject: + Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject")); + break; + case NSMutableArr_insertObjectAtIndex: { + IdentifierInfo *KeyIdents[] = { + &Ctx.Idents.get("insertObject"), + &Ctx.Idents.get("atIndex") + }; + Sel = Ctx.Selectors.getSelector(2, KeyIdents); + break; + } + case NSMutableArr_setObjectAtIndexedSubscript: { + IdentifierInfo *KeyIdents[] = { + &Ctx.Idents.get("setObject"), + &Ctx.Idents.get("atIndexedSubscript") + }; + Sel = Ctx.Selectors.getSelector(2, KeyIdents); + break; + } } return (NSArraySelectors[MK] = Sel); } @@ -209,6 +231,22 @@ Selector NSAPI::getNSDictionarySelector( Sel = Ctx.Selectors.getSelector(2, KeyIdents); break; } + case NSMutableDict_setObjectForKeyedSubscript: { + IdentifierInfo *KeyIdents[] = { + &Ctx.Idents.get("setObject"), + &Ctx.Idents.get("forKeyedSubscript") + }; + Sel = Ctx.Selectors.getSelector(2, KeyIdents); + break; + } + case NSMutableDict_setValueForKey: { + IdentifierInfo *KeyIdents[] = { + &Ctx.Idents.get("setValue"), + &Ctx.Idents.get("forKey") + }; + Sel = Ctx.Selectors.getSelector(2, KeyIdents); + break; + } } return (NSDictionarySelectors[MK] = Sel); } @@ -227,6 +265,63 @@ NSAPI::getNSDictionaryMethodKind(Selector Sel) { return None; } +Selector NSAPI::getNSSetSelector(NSSetMethodKind MK) const { + if (NSSetSelectors[MK].isNull()) { + Selector Sel; + switch (MK) { + case NSMutableSet_addObject: + Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject")); + break; + case NSOrderedSet_insertObjectAtIndex: { + IdentifierInfo *KeyIdents[] = { + &Ctx.Idents.get("insertObject"), + &Ctx.Idents.get("atIndex") + }; + Sel = Ctx.Selectors.getSelector(2, KeyIdents); + break; + } + case NSOrderedSet_setObjectAtIndex: { + IdentifierInfo *KeyIdents[] = { + &Ctx.Idents.get("setObject"), + &Ctx.Idents.get("atIndex") + }; + Sel = Ctx.Selectors.getSelector(2, KeyIdents); + break; + } + case NSOrderedSet_setObjectAtIndexedSubscript: { + IdentifierInfo *KeyIdents[] = { + &Ctx.Idents.get("setObject"), + &Ctx.Idents.get("atIndexedSubscript") + }; + Sel = Ctx.Selectors.getSelector(2, KeyIdents); + break; + } + case NSOrderedSet_replaceObjectAtIndexWithObject: { + IdentifierInfo *KeyIdents[] = { + &Ctx.Idents.get("replaceObjectAtIndex"), + &Ctx.Idents.get("withObject") + }; + Sel = Ctx.Selectors.getSelector(2, KeyIdents); + break; + } + } + return (NSSetSelectors[MK] = Sel); + } + + return NSSetSelectors[MK]; +} + +Optional<NSAPI::NSSetMethodKind> +NSAPI::getNSSetMethodKind(Selector Sel) { + for (unsigned i = 0; i != NumNSSetMethods; ++i) { + NSSetMethodKind MK = NSSetMethodKind(i); + if (Sel == getNSSetSelector(MK)) + return MK; + } + + return None; +} + Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, bool Instance) const { static const char *ClassSelectorName[NumNSNumberLiteralMethods] = { |