summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/NSAPI.cpp
diff options
context:
space:
mode:
authorAlex Denisov <1101.debian@gmail.com>2015-03-04 17:55:52 +0000
committerAlex Denisov <1101.debian@gmail.com>2015-03-04 17:55:52 +0000
commite1d882c726b53eebe4dbece9fdf7fb8dc6469f72 (patch)
tree60507712962fd8ed3cca070487229c64a1052884 /clang/lib/AST/NSAPI.cpp
parent4d9347993bbaaf9278df52d14e71e460a4afbd9f (diff)
downloadbcm5719-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.cpp97
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] = {
OpenPOWER on IntegriCloud