]> granicus.if.org Git - clang/commitdiff
Changed behavior of how we handle "NULL" summaries: just call
authorTed Kremenek <kremenek@apple.com>
Fri, 11 Apr 2008 20:11:19 +0000 (20:11 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 11 Apr 2008 20:11:19 +0000 (20:11 +0000)
GRSimpleVals::EvalCal(), and don't change reference counts.

Remove "getDoNothingSummary()", as a NULL summary does the same thing.

Added temporary hack for the "Get" rule for objects that return a pointer type:
treat them as non-owned CF objects.

Added test case to detect the release of a non-owned object.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49555 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CFRefCount.cpp
test/Analysis-Apple/CFString.c [new file with mode: 0644]

index 1748e450a364e79b921e09c7bbe7fb0f55fb8995..a115a71a2a301e24377cdbf72ea68f419a8f56c2 100644 (file)
@@ -136,7 +136,6 @@ class CFRefSummaryManager {
   
   CFRefSummary* getPersistentSummary(ArgEffects* AE, RetEffect RE);
   
-  CFRefSummary* getDoNothingSummary(unsigned Args);
   void FillDoNothing(unsigned Args);
 
   
@@ -366,16 +365,12 @@ void CFRefSummaryManager::FillDoNothing(unsigned Args) {
     ScratchArgs.push_back(DoNothing);
 }
 
-CFRefSummary* CFRefSummaryManager::getDoNothingSummary(unsigned Args) {
-  FillDoNothing(Args);
-  return getPersistentSummary(getArgEffects(), RetEffect::MakeNoRet());  
-}
 
 CFRefSummary*
 CFRefSummaryManager::getCFSummaryCreateRule(FunctionTypeProto* FT) {
  
   if (!isCFRefType(FT->getResultType()))
-    return getDoNothingSummary(FT->getNumArgs());
+    return NULL;
 
   assert (ScratchArgs.empty());
   
@@ -389,8 +384,16 @@ CFRefSummaryManager::getCFSummaryCreateRule(FunctionTypeProto* FT) {
 CFRefSummary*
 CFRefSummaryManager::getCFSummaryGetRule(FunctionTypeProto* FT) {
   
-  if (!isCFRefType(FT->getResultType()))
-    return getDoNothingSummary(FT->getNumArgs());
+  QualType RetTy = FT->getResultType();
+  
+  // FIXME: For now we assume that all pointer types returned are referenced
+  // counted.  Since this is the "Get" rule, we assume non-ownership, which
+  // works fine for things that are not reference counted.  We do this because
+  // some generic data structures return "void*".  We need something better
+  // in the future.
+  
+  if (!isCFRefType(RetTy) && !RetTy->isPointerType())
+    return NULL;
   
   assert (ScratchArgs.empty());
   
@@ -659,7 +662,7 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
   RefVal::Kind hasError = (RefVal::Kind) 0;
   
   if (!Summ) {
-    
+#if 0
     // This function has no summary.  Invalidate all reference-count state
     // for arguments passed to this function, and also nuke the values of
     // arguments passed-by-reference.
@@ -698,6 +701,10 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
     
     Builder.MakeNode(Dst, CE, Pred, St);
     return;
+#else
+    GRSimpleVals::EvalCall(Dst, Eng, Builder, CE, L, Pred);
+    return;
+#endif
   }
   
   // This function has a summary.  Evaluate the effect of the arguments.
diff --git a/test/Analysis-Apple/CFString.c b/test/Analysis-Apple/CFString.c
new file mode 100644 (file)
index 0000000..ebd9275
--- /dev/null
@@ -0,0 +1,30 @@
+// RUN: clang -checker-cfref -verify %s
+
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFArray.h>
+
+void f1() {
+  
+  // Create the array.
+  CFMutableArrayRef A = CFArrayCreateMutable(NULL, 10, &kCFTypeArrayCallBacks);
+
+  // Create a string.
+  CFStringRef s1 = CFStringCreateWithCString(NULL, "hello world",
+                                             kCFStringEncodingUTF8);
+
+  // Add the string to the array.
+  CFArrayAppendValue(A, s1);
+  
+  // Decrement the reference count.
+  CFRelease(s1); // no-warning
+  
+  // Get the string.  We don't own it.
+  s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0);
+  
+  // Release the array.
+  CFRelease(A); // no-warning
+  
+  // Release the string.  This is a bug.
+  CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}}
+}
+