From befc6d2eae269efa2da9c81d0be8dba144a74d47 Mon Sep 17 00:00:00 2001
From: Ted Kremenek <kremenek@apple.com>
Date: Thu, 26 Apr 2012 04:32:23 +0000
Subject: [PATCH] Teach RetainCountChecker that it doesn't quite understand
 pthread_setspecific and it should just give up when it sees it.  Fixes
 <rdar://problem/11282706>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155613 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp |  6 +++---
 test/Analysis/retain-release.m                     | 14 ++++++++++++++
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index b569e412c41..f7012799b8d 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -929,9 +929,9 @@ const RetainSummary * RetainSummaryManager::getSummary(const FunctionDecl *FD) {
     //  filters.
     assert(ScratchArgs.isEmpty());
 
-    if (FName == "pthread_create") {
-      // Part of: <rdar://problem/7299394>.  This will be addressed
-      // better with IPA.
+    if (FName == "pthread_create" || FName == "pthread_setspecific") {
+      // Part of: <rdar://problem/7299394> and <rdar://problem/11282706>.
+      // This will be addressed better with IPA.
       S = getPersistentStopSummary();
     } else if (FName == "NSMakeCollectable") {
       // Handle: id NSMakeCollectable(CFTypeRef)
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index 06c510e5dd3..3aa2656c62f 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -1055,10 +1055,14 @@ typedef struct _opaque_pthread_t *__darwin_pthread_t;
 typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t;
 typedef __darwin_pthread_t pthread_t;
 typedef __darwin_pthread_attr_t pthread_attr_t;
+typedef unsigned long __darwin_pthread_key_t;
+typedef __darwin_pthread_key_t pthread_key_t;
 
 int pthread_create(pthread_t *, const pthread_attr_t *,
                    void *(*)(void *), void *);
 
+int pthread_setspecific(pthread_key_t key, const void *value);
+
 void *rdar_7299394_start_routine(void *p) {
   [((id) p) release];
   return 0;
@@ -1071,6 +1075,16 @@ void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) {
   NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}}
 }
 
+//===----------------------------------------------------------------------===//
+// <rdar://problem/11282706> false positive with not understanding thread
+// local storage
+//===----------------------------------------------------------------------===//
+
+void rdar11282706(pthread_key_t key) {
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+  pthread_setspecific(key, (void*) number);
+}
+
 //===----------------------------------------------------------------------===//
 // <rdar://problem/7283567> False leak associated with call to 
 //                          CVPixelBufferCreateWithBytes ()
-- 
GitLab