aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-03-04 23:21:32 +0000
committerJordan Rose <jordan_rose@apple.com>2013-03-04 23:21:32 +0000
commit5aff3f1e9a66fa72576a6b04c8c319c17e0360c6 (patch)
tree7f6bab04356115f87f5329d54f0192eb8791a4c5
parent808383d2d6d58a7c7db85f8c7618fb74d821309f (diff)
[analyzer] Don't let cf_audited_transfer override CFRetain semantics.
We weren't treating a cf_audited_transfer CFRetain as returning +1 because its name doesn't contain "Create" or "Copy". Oops! Fortunately, the standard definitions of these functions are not marked audited. <rdar://problem/13339601> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176463 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp12
-rw-r--r--test/Analysis/retain-release-cf-audited.m33
2 files changed, 39 insertions, 6 deletions
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 3edc997503..856463a981 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -1133,12 +1133,7 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) {
if (S)
break;
- if (RetTy->isPointerType()) {
- if (FD->getAttr<CFAuditedTransferAttr>()) {
- S = getCFCreateGetRuleSummary(FD);
- break;
- }
-
+ if (RetTy->isPointerType()) {
// For CoreFoundation ('CF') types.
if (cocoa::isRefType(RetTy, "CF", FName)) {
if (isRetain(FD, FName))
@@ -1169,6 +1164,11 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) {
break;
}
+ if (FD->getAttr<CFAuditedTransferAttr>()) {
+ S = getCFCreateGetRuleSummary(FD);
+ break;
+ }
+
break;
}
diff --git a/test/Analysis/retain-release-cf-audited.m b/test/Analysis/retain-release-cf-audited.m
new file mode 100644
index 0000000000..c89172f70b
--- /dev/null
+++ b/test/Analysis/retain-release-cf-audited.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -verify %s -x objective-c++
+
+// The special thing about this file is that CFRetain and CFRelease are marked
+// as cf_audited_transfer.
+
+#pragma clang arc_cf_code_audited begin
+typedef const void * CFTypeRef;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+
+extern CFTypeRef CFCreateSomethingAudited();
+#pragma clang arc_cf_code_audited end
+
+extern CFTypeRef CFCreateSomethingUnaudited();
+
+void testAudited() {
+ CFTypeRef obj = CFCreateSomethingAudited(); // no-warning
+ CFRelease(obj); // no-warning
+
+ CFTypeRef obj2 = CFCreateSomethingAudited(); // expected-warning{{leak}}
+ CFRetain(obj2); // no-warning
+ CFRelease(obj2); // no-warning
+}
+
+void testUnaudited() {
+ CFTypeRef obj = CFCreateSomethingUnaudited(); // no-warning
+ CFRelease(obj); // no-warning
+
+ CFTypeRef obj2 = CFCreateSomethingUnaudited(); // expected-warning{{leak}}
+ CFRetain(obj2); // no-warning
+ CFRelease(obj2); // no-warning
+}