[analyzer] Per discussions with the Cocoa team, extend CF naming conventions to extend to camel case functions instead of just title case functions. Fixes <rdar://problem/9732321>.

llvm-svn: 135350
This commit is contained in:
Ted Kremenek 2011-07-16 19:50:36 +00:00
parent c85964ed90
commit 6dcbbe8547
2 changed files with 94 additions and 2 deletions

View File

@ -128,6 +128,45 @@ bool cocoa::isCocoaObjectRef(QualType Ty) {
}
bool coreFoundation::followsCreateRule(llvm::StringRef functionName) {
return functionName.find("Create") != StringRef::npos ||
functionName.find("Copy") != StringRef::npos;
llvm::StringRef::iterator it = functionName.begin();
llvm::StringRef::iterator start = it;
llvm::StringRef::iterator endI = functionName.end();
while (true) {
// Scan for the start of 'create' or 'copy'.
for ( ; it != endI ; ++it) {
// Search for the first character. It can either be 'C' or 'c'.
char ch = *it;
if (ch == 'C' || ch == 'c') {
++it;
break;
}
}
// Did we hit the end of the string? If so, we didn't find a match.
if (it == endI)
return false;
// Scan for *lowercase* 'reate' or 'opy', followed by no lowercase
// character.
llvm::StringRef suffix = functionName.substr(it - start);
if (suffix.startswith("reate")) {
it += 5;
}
else if (suffix.startswith("opy")) {
it += 3;
}
else {
// Keep scanning.
continue;
}
if (it == endI || !islower(*it))
return true;
// If we matched a lowercase character, it isn't the end of the
// word. Keep scanning.
}
return false;
}

View File

@ -1487,3 +1487,56 @@ void rdar9726279() {
NSValue *value = [[NSValue alloc] _prefix_initWithTwoDoubles:twoDoubles];
[value release];
}
// <rdar://problem/9732321>
// Test camelcase support for CF conventions. While Core Foundation APIs
// don't use camel casing, other code is allowed to use it.
CFArrayRef camelcase_create_1() {
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
}
CFArrayRef camelcase_createno() {
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}}
}
CFArrayRef camelcase_copy() {
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
}
CFArrayRef camelcase_copying() {
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}}
}
CFArrayRef copyCamelCase() {
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
}
CFArrayRef __copyCamelCase() {
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
}
CFArrayRef __createCamelCase() {
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
}
CFArrayRef camel_create() {
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
}
CFArrayRef camel_creat() {
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}}
}
CFArrayRef camel_copy() {
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
}
CFArrayRef camel_copyMachine() {
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
}
CFArrayRef camel_copymachine() {
return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}}
}