]> granicus.if.org Git - clang/commitdiff
The CF retain/release checker now assumes that allocations do not fail. Eventually...
authorTed Kremenek <kremenek@apple.com>
Mon, 23 Jun 2008 18:02:52 +0000 (18:02 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 23 Jun 2008 18:02:52 +0000 (18:02 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52632 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CFRefCount.cpp
test/Analysis/CFDate.m

index 7207c133ade53539bebcb386477f1acf4bf55600..d656e28662af1552a8d7e1867aec881a6206b11a 100644 (file)
@@ -113,8 +113,8 @@ namespace {
   
 class RetEffect {
 public:
-  enum Kind { NoRet = 0x0, Alias = 0x1, OwnedSymbol = 0x2,
-              NotOwnedSymbol = 0x3, ReceiverAlias=0x4 };
+  enum Kind { NoRet, Alias, OwnedSymbol, OwnedAllocatedSymbol,
+              NotOwnedSymbol, ReceiverAlias };
 
 private:
   unsigned Data;
@@ -133,7 +133,9 @@ public:
   
   static RetEffect MakeReceiverAlias() { return RetEffect(ReceiverAlias, 0); }
   
-  static RetEffect MakeOwned() { return RetEffect(OwnedSymbol, 0); }
+  static RetEffect MakeOwned(bool isAllocated = false) {
+    return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, 0);
+  }
   
   static RetEffect MakeNotOwned() { return RetEffect(NotOwnedSymbol, 0); }
   
@@ -534,7 +536,7 @@ RetainSummary* RetainSummaryManager::getCFSummaryCreateRule(FunctionDecl* FD) {
   //  just handle the default case.
 
   assert (ScratchArgs.empty());
-  return getPersistentSummary(RetEffect::MakeOwned());
+  return getPersistentSummary(RetEffect::MakeOwned(true));
 }
 
 RetainSummary* RetainSummaryManager::getCFSummaryGetRule(FunctionDecl* FD) {
@@ -619,7 +621,7 @@ RetainSummaryManager::getMethodSummary(ObjCMessageExpr* ME) {
       CStrInCStrNoCase(s, "new")) {
     
     RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet()
-                                : RetEffect::MakeOwned();  
+                                : RetEffect::MakeOwned(true);  
 
     RetainSummary* Summ = getPersistentSummary(E);
     ObjCMethSummaries[S] = Summ;
@@ -640,57 +642,15 @@ RetainSummaryManager::getInstanceMethodSummary(IdentifierInfo* ClsName,
     return I->second;
   
   return 0;
-
-#if 0
-  return 0;
-  
-  // Don't track anything if using GC.
-  if (isGCEnabled())
-    return 0;  
-
-  // Inspect the class name and selecrtor to determine if this method
-  //  creates new objects.
-  const char* cls = ClsName->getName();
-  
-  if (cls[0] == 'N' && cls[1] == 'S')  // Ignore preceding "NS" (if present).
-    cls += 2;
-  
-  // Heuristic: XXXwithYYY, where XXX is the class name with the "NS"
-  //  stripped off is usually an allocation.
-  
-  const char* s = S.getIdentifierInfoForSlot(0)->getName();  
-  
-  if (cls[0] == '\0' || s[0] == '\0' || tolower(cls[0]) != s[0])
-    return 0;
-  
-  // Now look at the rest of the characters.
-  ++cls; ++s;
-  unsigned len = strlen(cls);
-  
-  // If the prefix doesn't match, don't generate a special summary.
-  if (strncmp(cls, s, len) != 0)
-    return 0;
-  
-  // Look at the text after the prefix.
-  s += len;  
-  
-  if (!(s[0] == '\0' || strncmp(s, "With", 4) == 0))
-    return 0;
-  
-  // Generate and return the summary.
-  assert (ScratchArgs.empty());
-  
-  RetainSummary* Summ = getPersistentSummary(RetEffect::MakeOwned());
-  ObjCInstMethSummaries[S] = Summ;
-  return Summ;
-#endif
 }
 
 void RetainSummaryManager::InitializeInstMethSummaries() {
   
   assert (ScratchArgs.empty());
   
-  RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet() : RetEffect::MakeOwned();  
+  RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet()
+                              : RetEffect::MakeOwned(true);  
+  
   RetainSummary* Summ = getPersistentSummary(E);
   
   // Create the "alloc" selector.
@@ -713,7 +673,9 @@ void RetainSummaryManager::InitializeMethSummaries() {
   ObjCMethSummaries[ GetNullarySelector("init", Ctx) ] = Summ;
   
   // The next methods are allocators.
-  RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet() : RetEffect::MakeOwned();  
+  RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet()
+                              : RetEffect::MakeOwned(true);
+  
   Summ = getPersistentSummary(E);  
   
   // Create the "copy" selector.  
@@ -1249,6 +1211,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<ValueState>& Dst,
       break;
     }
       
+    case RetEffect::OwnedAllocatedSymbol:
     case RetEffect::OwnedSymbol: {
       unsigned Count = Builder.getCurrentBlockCount();
       SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
@@ -1261,6 +1224,10 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<ValueState>& Dst,
                             Ex, lval::SymbolVal(Sym),
                             Eng.getCFG().isBlkExpr(Ex), false);
       
+      // FIXME: Add a flag to the checker where allocations are allowed to fail.      
+      if (RE.getKind() == RetEffect::OwnedAllocatedSymbol)
+        St = StateMgr.AddNE(St, Sym, Eng.getBasicVals().getZeroWithPtrWidth());
+      
       break;
     }
       
index 9425f5930d78950e777abec1fa39bf129bb863b0..ed076c680b276c216bd99bc24117dbe8b5eda69d 100644 (file)
@@ -133,3 +133,11 @@ CFDateRef f8() {
   return date; // expected-warning{{leak}}
 }
 
+CFDateRef f9() {
+  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
+  int *p = 0;
+  // test that the checker assumes that CFDateCreate returns a non-null
+  // pointer
+  if (!date) *p = 1; // no-warning
+  return date;
+}