From: Richard Smith Date: Tue, 5 Sep 2017 21:46:22 +0000 (+0000) Subject: Fix memory leak after r312467. The ModuleMap is the owner of the global module object... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=76d554642795496a2936ac28b1b17e4adfa923c6;p=clang Fix memory leak after r312467. The ModuleMap is the owner of the global module object until it's reparented under a real module. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@312580 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index 9cca016751..4e600ce855 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -82,22 +82,26 @@ class ModuleMap { /// \brief The directory used for Clang-supplied, builtin include headers, /// such as "stdint.h". - const DirectoryEntry *BuiltinIncludeDir; + const DirectoryEntry *BuiltinIncludeDir = nullptr; /// \brief Language options used to parse the module map itself. /// /// These are always simple C language options. LangOptions MMapLangOpts; - // The module that the main source file is associated with (the module - // named LangOpts::CurrentModule, if we've loaded it). - Module *SourceModule; + /// The module that the main source file is associated with (the module + /// named LangOpts::CurrentModule, if we've loaded it). + Module *SourceModule = nullptr; + + /// The global module for the current TU, if we still own it. (Ownership is + /// transferred if/when we create an enclosing module. + std::unique_ptr PendingGlobalModule; /// \brief The top-level modules that are known. llvm::StringMap Modules; /// \brief The number of modules we have created in total. - unsigned NumCreatedModules; + unsigned NumCreatedModules = 0; public: /// \brief Flags describing the role of a module header. diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp index db2f952e3c..b01080e55a 100644 --- a/lib/Lex/ModuleMap.cpp +++ b/lib/Lex/ModuleMap.cpp @@ -256,8 +256,7 @@ ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo) : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target), - HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr), - SourceModule(nullptr), NumCreatedModules(0) { + HeaderInfo(HeaderInfo) { MMapLangOpts.LineComment = true; } @@ -747,10 +746,12 @@ std::pair ModuleMap::findOrCreateModule(StringRef Name, } Module *ModuleMap::createGlobalModuleForInterfaceUnit(SourceLocation Loc) { - auto *Result = new Module("", Loc, nullptr, /*IsFramework*/ false, - /*IsExplicit*/ true, NumCreatedModules++); - Result->Kind = Module::GlobalModuleFragment; - return Result; + assert(!PendingGlobalModule && "created multiple global modules"); + PendingGlobalModule.reset( + new Module("", Loc, nullptr, /*IsFramework*/ false, + /*IsExplicit*/ true, NumCreatedModules++)); + PendingGlobalModule->Kind = Module::GlobalModuleFragment; + return PendingGlobalModule.get(); } Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc, @@ -766,7 +767,10 @@ Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc, Modules[Name] = SourceModule = Result; // Reparent the current global module fragment as a submodule of this module. + assert(GlobalModule == PendingGlobalModule.get() && + "unexpected global module"); GlobalModule->setParent(Result); + PendingGlobalModule.release(); // now owned by parent // Mark the main source file as being within the newly-created module so that // declarations and macros are properly visibility-restricted to it.