Teach RetainCountChecker about 'pragma clang arc_cf_code_audited'.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162934 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 93a77f4..6710bfd 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -1145,6 +1145,11 @@
break;
if (RetTy->isPointerType()) {
+ if (FD->getAttr<CFAuditedTransferAttr>()) {
+ S = getCFCreateGetRuleSummary(FD);
+ break;
+ }
+
// For CoreFoundation ('CF') types.
if (cocoa::isRefType(RetTy, "CF", FName)) {
if (isRetain(FD, FName))
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index da1477b..4280d69 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -1885,3 +1885,16 @@
id unretained = @[]; // +0
CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
}
+//===----------------------------------------------------------------------===//
+// Test 'pragma clang arc_cf_code_audited' support.
+//===----------------------------------------------------------------------===//
+
+typedef void *MyCFType;
+#pragma clang arc_cf_code_audited begin
+MyCFType CreateMyCFType();
+#pragma clang arc_cf_code_audited end
+
+void test_custom_cf() {
+ MyCFType x = CreateMyCFType(); // expected-warning {{leak of an object stored into 'x'}}
+}
+