From 89be6ed38a376e9076768d56d6fa9712fcb0657e Mon Sep 17 00:00:00 2001 From: Kostya Serebryany <kcc@google.com> Date: Fri, 27 Dec 2013 08:11:08 +0000 Subject: [PATCH] Bury leaked pointers in a global array to silence a leak detector in --disable-free mode Summary: This is an alternative to http://llvm-reviews.chandlerc.com/D2475 suggested by Chandler. Reviewers: chandlerc, rnk, dblaikie CC: cfe-commits, earthdok Differential Revision: http://llvm-reviews.chandlerc.com/D2478 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@198073 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Frontend/CompilerInstance.h | 5 +++++ include/clang/Frontend/Utils.h | 5 +++++ lib/CodeGen/BackendUtil.cpp | 3 ++- lib/Frontend/CompilerInvocation.cpp | 16 ++++++++++++++++ lib/Frontend/FrontendAction.cpp | 5 +++-- lib/FrontendTool/ExecuteCompilerInvocation.cpp | 3 ++- tools/driver/cc1_main.cpp | 3 ++- 7 files changed, 35 insertions(+), 5 deletions(-) diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index ad752acf782..fa20ae48e4f 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/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 @@ public: } void resetAndLeakFileManager() { + BuryPointer(FileMgr.getPtr()); FileMgr.resetWithoutRelease(); } @@ -344,6 +346,7 @@ public: } void resetAndLeakSourceManager() { + BuryPointer(SourceMgr.getPtr()); SourceMgr.resetWithoutRelease(); } @@ -363,6 +366,7 @@ public: } void resetAndLeakPreprocessor() { + BuryPointer(PP.getPtr()); PP.resetWithoutRelease(); } @@ -381,6 +385,7 @@ public: } void resetAndLeakASTContext() { + BuryPointer(Context.getPtr()); Context.resetWithoutRelease(); } diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h index dff56c3a8a4..db52d5cf0dd 100644 --- a/include/clang/Frontend/Utils.h +++ b/include/clang/Frontend/Utils.h @@ -123,6 +123,11 @@ inline int getLastArgIntValue(const llvm::opt::ArgList &Args, 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 diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index f302ef7b37c..55970cdf842 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/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 @@ public: delete PerModulePasses; delete PerFunctionPasses; if (CodeGenOpts.DisableFree) - TM.take(); + BuryPointer(TM.take()); } llvm::OwningPtr<TargetMachine> TM; diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 71e6b74d38b..78a88f65f6b 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/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 @@ int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default, } 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; +} } diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp index 49d01f9d372..31889f1fff8 100644 --- a/lib/Frontend/FrontendAction.cpp +++ b/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 @@ void FrontendAction::EndSourceFile() { // // 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 { diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp index e22f9ba0523..e14fb2340e6 100644 --- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/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 @@ bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) { return false; bool Success = Clang->ExecuteAction(*Act); if (Clang->getFrontendOpts().DisableFree) - Act.take(); + BuryPointer(Act.take()); return Success; } diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp index 5b3b5ad6500..28ada6944e8 100644 --- a/tools/driver/cc1_main.cpp +++ b/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 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd, if (Clang->getFrontendOpts().DisableFree) { if (llvm::AreStatisticsEnabled() || Clang->getFrontendOpts().ShowStats) llvm::PrintStatistics(); - Clang.take(); + BuryPointer(Clang.take()); return !Success; } -- GitLab