From: Ted Kremenek Date: Thu, 10 Apr 2008 22:58:08 +0000 (+0000) Subject: Fix some bonehead bugs in summary generation in CFRefCount. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3ea0b6a0870889fc2822549ed52d98bf5e292a24;p=clang Fix some bonehead bugs in summary generation in CFRefCount. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49503 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp index 4537a7f347..defa7a1511 100644 --- a/Driver/ASTConsumers.cpp +++ b/Driver/ASTConsumers.cpp @@ -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 diff --git a/include/clang/Analysis/LocalCheckers.h b/include/clang/Analysis/LocalCheckers.h index 96fd5884e9..8f963b71c4 100644 --- a/include/clang/Analysis/LocalCheckers.h +++ b/include/clang/Analysis/LocalCheckers.h @@ -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 diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 85c8e86500..54d67b5079 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -37,14 +37,10 @@ namespace { namespace llvm { template <> struct FoldingSetTrait { - 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 SummarySetTy; typedef llvm::DenseMap 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); +}