[PATCH] Bury leaked pointers in a global array to silence a leak detector in --disable-free mode

Kostya Serebryany kcc at google.com
Thu Dec 26 23:10:23 PST 2013


Hi chandlerc, rnk, dblaikie,

This is an alternative to http://llvm-reviews.chandlerc.com/D2475
suggested by Chandler.

http://llvm-reviews.chandlerc.com/D2478

Files:
  include/clang/Frontend/Utils.h
  include/clang/Frontend/CompilerInstance.h
  tools/driver/cc1_main.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Frontend/FrontendAction.cpp
  lib/CodeGen/BackendUtil.cpp
  lib/FrontendTool/ExecuteCompilerInvocation.cpp

Index: include/clang/Frontend/Utils.h
===================================================================
--- include/clang/Frontend/Utils.h
+++ include/clang/Frontend/Utils.h
@@ -123,6 +123,11 @@
   return getLastArgIntValue(Args, Id, Default, &Diags);
 }
 
+// When Clang->getFrontendOpts().DisableFree is set we don't delete some of the
+// global objects, but we don't want LeakDetectors to complain, so we bury them
+// in a globally visible array.
+void BuryPointer(const void *Ptr);
+
 } // end namespace clang
 
 #endif
Index: include/clang/Frontend/CompilerInstance.h
===================================================================
--- include/clang/Frontend/CompilerInstance.h
+++ include/clang/Frontend/CompilerInstance.h
@@ -13,6 +13,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/Utils.h"
 #include "clang/Lex/ModuleLoader.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
@@ -325,6 +326,7 @@
   }
   
   void resetAndLeakFileManager() {
+    BuryPointer(FileMgr.getPtr());
     FileMgr.resetWithoutRelease();
   }
 
@@ -344,6 +346,7 @@
   }
   
   void resetAndLeakSourceManager() {
+    BuryPointer(SourceMgr.getPtr());
     SourceMgr.resetWithoutRelease();
   }
 
@@ -363,6 +366,7 @@
   }
 
   void resetAndLeakPreprocessor() {
+    BuryPointer(PP.getPtr());
     PP.resetWithoutRelease();
   }
 
@@ -381,6 +385,7 @@
   }
   
   void resetAndLeakASTContext() {
+    BuryPointer(Context.getPtr());
     Context.resetWithoutRelease();
   }
 
Index: tools/driver/cc1_main.cpp
===================================================================
--- tools/driver/cc1_main.cpp
+++ tools/driver/cc1_main.cpp
@@ -21,6 +21,7 @@
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/TextDiagnosticBuffer.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Frontend/Utils.h"
 #include "clang/FrontendTool/Utils.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/LinkAllPasses.h"
@@ -112,7 +113,7 @@
   if (Clang->getFrontendOpts().DisableFree) {
     if (llvm::AreStatisticsEnabled() || Clang->getFrontendOpts().ShowStats)
       llvm::PrintStatistics();
-    Clang.take();
+    BuryPointer(Clang.take());
     return !Success;
   }
 
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -28,6 +28,7 @@
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/OptTable.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Support/Atomic.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Host.h"
@@ -1827,4 +1828,19 @@
   }
   return Res;
 }
+
+void BuryPointer(const void *Ptr) {
+  // This function may be called only a small fixed amount of times per each
+  // invocation, otherwise we do actually have a leak which we want to report.
+  // If this function is called more than kGraveYardMaxSize times, the pointers
+  // will not be properly buried and a leak detector will report a leak, which
+  // is what we want in such case.
+  static const size_t kGraveYardMaxSize = 16;
+  static const void *GraveYard[kGraveYardMaxSize];
+  static llvm::sys::cas_flag GraveYardSize;
+  llvm::sys::cas_flag Idx = llvm::sys::AtomicIncrement(&GraveYardSize) - 1;
+  if (Idx >= kGraveYardMaxSize)
+    return;
+  GraveYard[Idx] = Ptr;
+}
 }
Index: lib/Frontend/FrontendAction.cpp
===================================================================
--- lib/Frontend/FrontendAction.cpp
+++ lib/Frontend/FrontendAction.cpp
@@ -17,6 +17,7 @@
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/FrontendPluginRegistry.h"
 #include "clang/Frontend/LayoutOverrideSource.h"
+#include "clang/Frontend/Utils.h"
 #include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/Preprocessor.h"
@@ -403,9 +404,9 @@
   //
   // FIXME: There is more per-file stuff we could just drop here?
   if (CI.getFrontendOpts().DisableFree) {
-    CI.takeASTConsumer();
+    BuryPointer(CI.takeASTConsumer());
     if (!isCurrentFileAST()) {
-      CI.takeSema();
+      BuryPointer(CI.takeSema());
       CI.resetAndLeakASTContext();
     }
   } else {
Index: lib/CodeGen/BackendUtil.cpp
===================================================================
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -13,6 +13,7 @@
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/Utils.h"
 #include "llvm/Analysis/Verifier.h"
 #include "llvm/Assembly/PrintModulePass.h"
 #include "llvm/Bitcode/ReaderWriter.h"
@@ -117,7 +118,7 @@
     delete PerModulePasses;
     delete PerFunctionPasses;
     if (CodeGenOpts.DisableFree)
-      TM.take();
+      BuryPointer(TM.take());
   }
 
   llvm::OwningPtr<TargetMachine> TM;
Index: lib/FrontendTool/ExecuteCompilerInvocation.cpp
===================================================================
--- lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -21,6 +21,7 @@
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/FrontendPluginRegistry.h"
+#include "clang/Frontend/Utils.h"
 #include "clang/Rewrite/Frontend/FrontendActions.h"
 #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
 #include "llvm/Option/OptTable.h"
@@ -236,6 +237,6 @@
     return false;
   bool Success = Clang->ExecuteAction(*Act);
   if (Clang->getFrontendOpts().DisableFree)
-    Act.take();
+    BuryPointer(Act.take());
   return Success;
 }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2478.1.patch
Type: text/x-patch
Size: 5804 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131226/c859be6c/attachment.bin>


More information about the cfe-commits mailing list