summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-10-01 00:48:56 +0000
committerJohn McCall <rjmccall@apple.com>2011-10-01 00:48:56 +0000
commit525f05597f99fc16f399fd7c3bb305b8ed5166f4 (patch)
tree2e2080490f375a640a58fd5acab5cc706ea1cb71
parent1ed54f50c54400c5968396b4aaa0704c0f1e3a72 (diff)
downloadbcm5719-llvm-525f05597f99fc16f399fd7c3bb305b8ed5166f4.tar.gz
bcm5719-llvm-525f05597f99fc16f399fd7c3bb305b8ed5166f4.zip
Tweak the interface for analyzing the CF conventions for a name
to take a FunctionDecl* instead of an llvm::StringRef. Eventually we might push more logic in there, like using slightly different conventions for C++ methods. Also, fix a bug where 'copy' and 'create' were being caught in non-camel-cased strings. We want copyFoo and CopyFoo and XCopy but not Xcopy or xcopy. llvm-svn: 140911
-rw-r--r--clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h7
-rw-r--r--clang/lib/Analysis/CocoaConventions.cpp12
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp14
-rw-r--r--clang/test/Analysis/retain-release.mm10
4 files changed, 31 insertions, 12 deletions
diff --git a/clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h b/clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h
index 25465f6b5d2..fa8afccfcd8 100644
--- a/clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h
+++ b/clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h
@@ -14,12 +14,13 @@
#ifndef LLVM_CLANG_ANALYSIS_DS_COCOA
#define LLVM_CLANG_ANALYSIS_DS_COCOA
+#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/StringRef.h"
-#include "clang/AST/Type.h"
namespace clang {
-
+class FunctionDecl;
class ObjCMethodDecl;
+class QualType;
namespace ento {
namespace cocoa {
@@ -43,7 +44,7 @@ namespace cocoa {
namespace coreFoundation {
bool isCFObjectRef(QualType T);
- bool followsCreateRule(StringRef functionName);
+ bool followsCreateRule(const FunctionDecl *FD);
}
}} // end: "clang:ento"
diff --git a/clang/lib/Analysis/CocoaConventions.cpp b/clang/lib/Analysis/CocoaConventions.cpp
index 3926ce55aa2..8acd1892f9c 100644
--- a/clang/lib/Analysis/CocoaConventions.cpp
+++ b/clang/lib/Analysis/CocoaConventions.cpp
@@ -125,7 +125,13 @@ bool cocoa::isCocoaObjectRef(QualType Ty) {
return false;
}
-bool coreFoundation::followsCreateRule(StringRef functionName) {
+bool coreFoundation::followsCreateRule(const FunctionDecl *fn) {
+ // For now, *just* base this on the function name, not on anything else.
+
+ const IdentifierInfo *ident = fn->getIdentifier();
+ if (!ident) return false;
+ StringRef functionName = ident->getName();
+
StringRef::iterator it = functionName.begin();
StringRef::iterator start = it;
StringRef::iterator endI = functionName.end();
@@ -136,6 +142,10 @@ bool coreFoundation::followsCreateRule(StringRef functionName) {
// Search for the first character. It can either be 'C' or 'c'.
char ch = *it;
if (ch == 'C' || ch == 'c') {
+ // Make sure this isn't something like 'recreate' or 'Scopy'.
+ if (ch == 'c' && it != start && isalpha(*(it - 1)))
+ continue;
+
++it;
break;
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 695cc037e86..0a23d5b6bb8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -623,8 +623,7 @@ public:
RetainSummary* getCFSummaryCreateRule(const FunctionDecl *FD);
RetainSummary* getCFSummaryGetRule(const FunctionDecl *FD);
- RetainSummary* getCFCreateGetRuleSummary(const FunctionDecl *FD,
- StringRef FName);
+ RetainSummary* getCFCreateGetRuleSummary(const FunctionDecl *FD);
RetainSummary* getPersistentSummary(ArgEffects AE, RetEffect RetEff,
ArgEffect ReceiverEff = DoNothing,
@@ -1000,7 +999,7 @@ RetainSummary* RetainSummaryManager::getSummary(const FunctionDecl *FD) {
else if (isMakeCollectable(FD, FName))
S = getUnarySummary(FT, cfmakecollectable);
else
- S = getCFCreateGetRuleSummary(FD, FName);
+ S = getCFCreateGetRuleSummary(FD);
break;
}
@@ -1010,7 +1009,7 @@ RetainSummary* RetainSummaryManager::getSummary(const FunctionDecl *FD) {
if (isRetain(FD, FName))
S = getUnarySummary(FT, cfretain);
else
- S = getCFCreateGetRuleSummary(FD, FName);
+ S = getCFCreateGetRuleSummary(FD);
break;
}
@@ -1019,7 +1018,7 @@ RetainSummary* RetainSummaryManager::getSummary(const FunctionDecl *FD) {
if (cocoa::isRefType(RetTy, "DADisk") ||
cocoa::isRefType(RetTy, "DADissenter") ||
cocoa::isRefType(RetTy, "DASessionRef")) {
- S = getCFCreateGetRuleSummary(FD, FName);
+ S = getCFCreateGetRuleSummary(FD);
break;
}
@@ -1072,9 +1071,8 @@ RetainSummary* RetainSummaryManager::getSummary(const FunctionDecl *FD) {
}
RetainSummary*
-RetainSummaryManager::getCFCreateGetRuleSummary(const FunctionDecl *FD,
- StringRef FName) {
- if (coreFoundation::followsCreateRule(FName))
+RetainSummaryManager::getCFCreateGetRuleSummary(const FunctionDecl *FD) {
+ if (coreFoundation::followsCreateRule(FD))
return getCFSummaryCreateRule(FD);
return getCFSummaryGetRule(FD);
diff --git a/clang/test/Analysis/retain-release.mm b/clang/test/Analysis/retain-release.mm
index 7c6f9e3c4aa..bae8dc33925 100644
--- a/clang/test/Analysis/retain-release.mm
+++ b/clang/test/Analysis/retain-release.mm
@@ -304,4 +304,14 @@ void test_smartpointer_3() {
foo.noAdopt(x);
}
+extern CFStringRef ElectronMicroscopyEngage(void);
+void test_microscopy() {
+ NSString *token = (NSString*) ElectronMicroscopyEngage();
+ [token release]; // expected-warning {{object that is not owned}}
+}
+extern CFStringRef Scopy(void);
+void test_Scopy() {
+ NSString *token = (NSString*) Scopy();
+ [token release]; // expected-warning {{object that is not owned}}
+}
OpenPOWER on IntegriCloud