aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-07-01 18:22:13 +0000
committerDouglas Gregor <dgregor@apple.com>2011-07-01 18:22:13 +0000
commit01b6e31a62e2265849f4388b9be6be0a5d13348d (patch)
treebc1307c9f9ee592ee00c07892443177db88a9e52
parent0e5abb8479543bf2517bc4a1332017d627fa61bc (diff)
When we create a precompiled preamble, don't copy the
CompilerInvocation on the stack, because other objects (e.g., the CompilerInstance) maintain an intrusive reference-counted pointer to the CompilerInvocation. This doesn't matter in the normal case, because we take back the CompilerInvocation. However, during crash recovery, this leads to us trying to free an object on the stack, and hilarity ensues. Fixes <rdar://problem/9652540>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134245 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Frontend/ASTUnit.h2
-rw-r--r--lib/Frontend/ASTUnit.cpp15
2 files changed, 10 insertions, 7 deletions
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 339297eb93..b44199570a 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -363,7 +363,7 @@ private:
unsigned MaxLines, bool &CreatedBuffer);
llvm::MemoryBuffer *getMainBufferWithPrecompiledPreamble(
- CompilerInvocation PreambleInvocation,
+ const CompilerInvocation &PreambleInvocationIn,
bool AllowRebuild = true,
unsigned MaxLines = 0);
void RealizeTopLevelDeclsFromPreamble();
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 8827116f2e..86a9a351d2 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -1150,16 +1150,19 @@ static llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old,
/// buffer that should be used in place of the main file when doing so.
/// Otherwise, returns a NULL pointer.
llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
- CompilerInvocation PreambleInvocation,
+ const CompilerInvocation &PreambleInvocationIn,
bool AllowRebuild,
unsigned MaxLines) {
- FrontendOptions &FrontendOpts = PreambleInvocation.getFrontendOpts();
+
+ llvm::IntrusiveRefCntPtr<CompilerInvocation>
+ PreambleInvocation(new CompilerInvocation(PreambleInvocationIn));
+ FrontendOptions &FrontendOpts = PreambleInvocation->getFrontendOpts();
PreprocessorOptions &PreprocessorOpts
- = PreambleInvocation.getPreprocessorOpts();
+ = PreambleInvocation->getPreprocessorOpts();
bool CreatedPreambleBuffer = false;
std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble
- = ComputePreamble(PreambleInvocation, MaxLines, CreatedPreambleBuffer);
+ = ComputePreamble(*PreambleInvocation, MaxLines, CreatedPreambleBuffer);
// If ComputePreamble() Take ownership of the
llvm::OwningPtr<llvm::MemoryBuffer> OwnedPreambleBuffer;
@@ -1260,7 +1263,7 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
// have occurred in the preamble.
getDiagnostics().Reset();
ProcessWarningOptions(getDiagnostics(),
- PreambleInvocation.getDiagnosticOpts());
+ PreambleInvocation->getDiagnosticOpts());
getDiagnostics().setNumWarnings(NumWarningsInPreamble);
if (StoredDiagnostics.size() > NumStoredDiagnosticsInPreamble)
StoredDiagnostics.erase(
@@ -1357,7 +1360,7 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
CICleanup(Clang.get());
- Clang->setInvocation(&PreambleInvocation);
+ Clang->setInvocation(&*PreambleInvocation);
OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second;
// Set up diagnostics, capturing all of the diagnostics produced.