]> granicus.if.org Git - clang/commitdiff
Provide the option to run the CF-retain checker in GC enabled mode.
authorTed Kremenek <kremenek@apple.com>
Tue, 29 Apr 2008 05:13:59 +0000 (05:13 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 29 Apr 2008 05:13:59 +0000 (05:13 +0000)
The transfer functions for the checker don't do anything special yet in GC mode.

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

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

index 2f04ab78d4fed5567dbd73fe6ed080d28ff5eb96..c01e4edb0d1d2851e9d347dfc51ebb40c1142f39 100644 (file)
@@ -690,7 +690,7 @@ public:
   virtual bool printFuncDeclStart() { return false; }
 
   virtual const char* getCheckerName() = 0;
-  virtual GRTransferFuncs* getTransferFunctions() = 0;
+  virtual void getTransferFunctions(std::vector<GRTransferFuncs*>& TFs) = 0;
 };
 } // end anonymous namespace
 
@@ -732,22 +732,30 @@ void CheckerConsumer::VisitCFG(CFG& C, Decl& CD) {
   else
     llvm::cerr << '\n';    
   
-  // Construct the analysis engine.
-  GRExprEngine Eng(C, CD, *Ctx);
+  std::vector<GRTransferFuncs*> TFs;
+  getTransferFunctions(TFs);
   
-  // Set base transfer functions.
-  llvm::OwningPtr<GRTransferFuncs> TF(getTransferFunctions());
-  Eng.setTransferFunctions(TF.get());
-  
-  // Execute the worklist algorithm.
-  Eng.ExecuteWorkList();
-  
-  // Display warnings.
-  Eng.EmitWarnings(Diags, PD.get());
-  
-#ifndef NDEBUG
-  if (Visualize) Eng.ViewGraph(TrimGraph);
-#endif
+  while (!TFs.empty()) {
+
+    // Construct the analysis engine.
+    GRExprEngine Eng(C, CD, *Ctx);
+    
+    // Set base transfer functions.
+    llvm::OwningPtr<GRTransferFuncs> TF(TFs.back());
+    TFs.pop_back();
+      
+    Eng.setTransferFunctions(TF.get());
+    
+    // Execute the worklist algorithm.
+    Eng.ExecuteWorkList();
+    
+    // Display warnings.
+    Eng.EmitWarnings(Diags, PD.get());
+    
+  #ifndef NDEBUG
+    if (Visualize) Eng.ViewGraph(TrimGraph);
+  #endif
+  }
 }
 
 //===----------------------------------------------------------------------===//
@@ -765,8 +773,8 @@ public:
 
   virtual const char* getCheckerName() { return "GRSimpleVals"; }
   
-  virtual GRTransferFuncs* getTransferFunctions() {
-    return MakeGRSimpleValsTF();
+  virtual void getTransferFunctions(std::vector<GRTransferFuncs*>& TFs) {
+    return TFs.push_back(MakeGRSimpleValsTF());
   }
 };
 } // end anonymous namespace
@@ -789,19 +797,34 @@ ASTConsumer* clang::CreateGRSimpleVals(Diagnostic &Diags,
 
 namespace {
 class CFRefCountCheckerVisitor : public CheckerConsumer {
+  const LangOptions& LangOpts;
 public:
   CFRefCountCheckerVisitor(Diagnostic &diags, Preprocessor* pp,
                            PreprocessorFactory* ppf,
+                           const LangOptions& lopts,
                            const std::string& fname,
                            const std::string& htmldir,
                            bool visualize, bool trim, bool analyzeAll)
   : CheckerConsumer(diags, pp, ppf, fname, htmldir, visualize,
-                    trim, analyzeAll) {}
+                    trim, analyzeAll), LangOpts(lopts) {}
   
   virtual const char* getCheckerName() { return "CFRefCountChecker"; }
   
-  virtual GRTransferFuncs* getTransferFunctions() {
-    return MakeCFRefCountTF(*Ctx);
+  virtual void getTransferFunctions(std::vector<GRTransferFuncs*>& TFs) {
+    switch (LangOpts.getGCMode()) {
+      case LangOptions::NonGC:
+        TFs.push_back(MakeCFRefCountTF(*Ctx, false));
+        break;
+        
+      case LangOptions::GCOnly:
+        TFs.push_back(MakeCFRefCountTF(*Ctx, true));
+        break;
+        
+      case LangOptions::HybridGC:
+        TFs.push_back(MakeCFRefCountTF(*Ctx, false));
+        TFs.push_back(MakeCFRefCountTF(*Ctx, true));
+        break;
+    }
   }
 };
 } // end anonymous namespace
@@ -809,13 +832,15 @@ public:
 ASTConsumer* clang::CreateCFRefChecker(Diagnostic &Diags,
                                        Preprocessor* PP,
                                        PreprocessorFactory* PPF,
+                                       const LangOptions& LangOpts,
                                        const std::string& FunctionName,
                                        const std::string& HTMLDir,
                                        bool Visualize, bool TrimGraph,
                                        bool AnalyzeAll) {
   
-  return new CFRefCountCheckerVisitor(Diags, PP, PPF, FunctionName, HTMLDir,
-                                      Visualize, TrimGraph, AnalyzeAll);
+  return new CFRefCountCheckerVisitor(Diags, PP, PPF, LangOpts, FunctionName,
+                                      HTMLDir, Visualize, TrimGraph,
+                                      AnalyzeAll);
 }
 
 //===----------------------------------------------------------------------===//
index 7ef42a0707593e83dc3b819bd78d50f617c5c091..7037ade1ddff8ad52405931f01df4141091f74f5 100644 (file)
@@ -53,6 +53,7 @@ ASTConsumer *CreateGRSimpleVals(Diagnostic &Diags,
   
 ASTConsumer *CreateCFRefChecker(Diagnostic &Diags,
                                 Preprocessor* PP, PreprocessorFactory* PPF,
+                                const LangOptions& LangOpts,
                                 const std::string& Function,
                                 const std::string& HTMLDir, bool Visualize,
                                 bool TrimGraph, bool AnalyzeAll);
index 0b9841687b6b980c787f283896e78149b7189d87..62f570f6277c2d981a7d392006dd2174e26bae31 100644 (file)
@@ -1132,7 +1132,8 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile,
                                 OutputFile, VisualizeEG, TrimGraph, AnalyzeAll);
       
     case CheckerCFRef:
-      return CreateCFRefChecker(Diag, PP, PPF, AnalyzeSpecificFunction,
+      return CreateCFRefChecker(Diag, PP, PPF, LangOpts,
+                                AnalyzeSpecificFunction,
                                 OutputFile, VisualizeEG, TrimGraph, AnalyzeAll);
       
     case TestSerialization:
index 6dcad7f3766b076303ad5f0849b361dbac1625a3..bf4f30a337cdc1851dfb402fccfb5de8d284432b 100644 (file)
@@ -31,7 +31,7 @@ void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
                               bool FullUninitTaint=false);
   
 GRTransferFuncs* MakeGRSimpleValsTF();
-GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx); 
+GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled); 
 BugType* MakeDeadStoresChecker();
   
 } // end namespace clang
index ad72d27a82f8e2dc44f2333f9adeefe1b170a39e..730c5311f541ba5547da19b4ed89631fe19d0194 100644 (file)
@@ -590,7 +590,8 @@ public:
 private:
   // Instance variables.
   
-  CFRefSummaryManager Summaries;
+  CFRefSummaryManager Summaries;  
+  const bool          GCEnabled;  
   RefBFactoryTy       RefBFactory;
      
   UseAfterReleasesTy UseAfterReleases;
@@ -636,8 +637,9 @@ private:
   
 public:
   
-  CFRefCount(ASTContext& Ctx)
+  CFRefCount(ASTContext& Ctx, bool gcenabled)
     : Summaries(Ctx),
+      GCEnabled(gcenabled),
       RetainSelector(GetUnarySelector("retain", Ctx)),
       ReleaseSelector(GetUnarySelector("release", Ctx)) {}
   
@@ -1575,6 +1577,6 @@ void Leak::GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes) {
 // Transfer function creation for external clients.
 //===----------------------------------------------------------------------===//
 
-GRTransferFuncs* clang::MakeCFRefCountTF(ASTContext& Ctx) {
-  return new CFRefCount(Ctx);
+GRTransferFuncs* clang::MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled) {
+  return new CFRefCount(Ctx, GCEnabled);
 }