]> granicus.if.org Git - clang/commitdiff
Fix some bonehead bugs in summary generation in CFRefCount.
authorTed Kremenek <kremenek@apple.com>
Thu, 10 Apr 2008 22:58:08 +0000 (22:58 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 10 Apr 2008 22:58:08 +0000 (22:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49503 91177308-0d34-0410-b5e6-96231b3b80d8

Driver/ASTConsumers.cpp
include/clang/Analysis/LocalCheckers.h
lib/Analysis/CFRefCount.cpp

index 4537a7f3472c07ce507fe882fc40f61469a079e5..defa7a151151b1c028b3e9ef2966dfa3aa68a7c7 100644 (file)
@@ -636,6 +636,7 @@ ASTConsumer *clang::CreateUnitValsChecker(Diagnostic &Diags) {
 namespace {
   
 class CheckerConsumer : public CFGVisitor {
+protected:
   Diagnostic &Diags;
   ASTContext* Ctx;
   const std::string& HTMLDir;
@@ -755,7 +756,7 @@ public:
   virtual const char* getCheckerName() { return "CFRefCountChecker"; }
   
   virtual GRTransferFuncs* getTransferFunctions() {
-    return MakeCFRefCountTF();
+    return MakeCFRefCountTF(*Ctx);
   }
 };
 } // end anonymous namespace
index 96fd5884e90bfed3998866c90e82cb51dda2d4b4..8f963b71c4bb8f30c7128a09ea43d3172e437531 100644 (file)
@@ -30,7 +30,7 @@ void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
                               bool FullUninitTaint=false);
   
 GRTransferFuncs* MakeGRSimpleValsTF();
-GRTransferFuncs* MakeCFRefCountTF();
+GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx);
   
 } // end namespace clang
 
index 85c8e8650050ff1edd4fc5182c498a46ea20acc6..54d67b5079a8076fcb9f6bde3b39cefa9238d504 100644 (file)
@@ -37,14 +37,10 @@ namespace {
 
 namespace llvm {
   template <> struct FoldingSetTrait<ArgEffects> {
-    static void Profile(const ArgEffects& X, FoldingSetNodeID ID) {
+    static void Profile(const ArgEffects& X, FoldingSetNodeID& ID) {
       for (ArgEffects::const_iterator I = X.begin(), E = X.end(); I!= E; ++I)
         ID.AddInteger((unsigned) *I);
-    }
-    
-    static void Profile(ArgEffects& X, FoldingSetNodeID ID) {
-      Profile(X, ID);
-    }
+    }    
   };
 } // end llvm namespace
 
@@ -56,7 +52,7 @@ public:
 
 private:
   unsigned Data;
-  RetEffect(Kind k, unsigned D) { Data = (Data << 2) | (unsigned) k; }
+  RetEffect(Kind k, unsigned D) { Data = (D << 2) | (unsigned) k; }
   
 public:
 
@@ -64,7 +60,7 @@ public:
 
   unsigned getValue() const { 
     assert(getKind() == Alias);
-    return Data & ~0x3;
+    return Data >> 2;
   }
   
   static RetEffect MakeAlias(unsigned Idx) { return RetEffect(Alias, Idx); }
@@ -118,12 +114,12 @@ class CFRefSummaryManager {
   typedef llvm::FoldingSet<CFRefSummary>                SummarySetTy;
   typedef llvm::DenseMap<FunctionDecl*, CFRefSummary*>  SummaryMapTy;
   
-  SummarySetTy           SummarySet;
-  SummaryMapTy           SummaryMap;  
-  AESetTy                AESet;  
-  llvm::BumpPtrAllocator BPAlloc;
-  
-  ArgEffects             ScratchArgs;
+  ASTContext& Ctx;  
+  SummarySetTy SummarySet;
+  SummaryMapTy SummaryMap;  
+  AESetTy AESet;  
+  llvm::BumpPtrAllocator BPAlloc;  
+  ArgEffects ScratchArgs;
   
   
   ArgEffects*   getArgEffects();
@@ -138,7 +134,7 @@ class CFRefSummaryManager {
   CFRefSummary* getPersistentSummary(ArgEffects* AE, RetEffect RE);
   
 public:
-  CFRefSummaryManager() {}
+  CFRefSummaryManager(ASTContext& ctx) : Ctx(ctx) {}
   ~CFRefSummaryManager();
   
   CFRefSummary* getSummary(FunctionDecl* FD, ASTContext& Ctx);
@@ -306,19 +302,26 @@ CFRefSummary* CFRefSummaryManager::getCannedCFSummary(FunctionTypeProto* FT,
   const char* TDName = ArgT->getDecl()->getIdentifier()->getName();
   assert (TDName);
   
-  if (strcmp("CFTypeRef", TDName) == 0)
+  if (strcmp("CFTypeRef", TDName) != 0)
     return NULL;
   
   if (!ArgT->isPointerType())
     return NULL;
-  
-  // Check the return type.  It should also be "CFTypeRef".
-  
+
   QualType RetTy = FT->getResultType();
   
-  if (RetTy.getTypePtr() != ArgT)
-    return NULL;
-  
+  if (isRetain) {
+    // CFRetain: the return type should also be "CFTypeRef".
+    if (RetTy.getTypePtr() != ArgT)
+      return NULL;
+  }
+  else {
+    // CFRelease: the return type should be void.
+    
+    if (RetTy != Ctx.VoidTy)
+      return NULL;
+  }
+    
   // The function's interface checks out.  Generate a canned summary.
   
   assert (ScratchArgs.empty());
@@ -446,11 +449,11 @@ class VISIBILITY_HIDDEN RefVal {
   unsigned Data;
   
   RefVal(unsigned K, unsigned D) : Data((D << 3) | K) {
-    assert ((K & ~0x5) == 0x0);
+    assert ((K & ~0x7) == 0x0);
   }
   
   RefVal(unsigned K) : Data(K) {
-    assert ((K & ~0x5) == 0x0);
+    assert ((K & ~0x7) == 0x0);
   }
 
 public:  
@@ -554,7 +557,7 @@ class VISIBILITY_HIDDEN CFRefCount : public GRSimpleVals {
  
   
 public:
-  CFRefCount() {}
+  CFRefCount(ASTContext& Ctx) : Summaries(Ctx) {}
   virtual ~CFRefCount() {}
   
   virtual void RegisterChecks(GRExprEngine& Eng);
@@ -877,4 +880,6 @@ void BadRelease::EmitWarnings(BugReporter& BR) {
 // Transfer function creation for external clients.
 //===----------------------------------------------------------------------===//
 
-GRTransferFuncs* clang::MakeCFRefCountTF() { return new CFRefCount(); }  
+GRTransferFuncs* clang::MakeCFRefCountTF(ASTContext& Ctx) {
+  return new CFRefCount(Ctx);
+}