[libclang] Make sure we don't ever leave a StoredDiagnostic associated with

a SourceManager that has already been deleted, rdar://10768346.

llvm-svn: 149532
This commit is contained in:
Argyrios Kyrtzidis 2012-02-01 19:54:02 +00:00
parent c48190c10a
commit 38bacf3429
1 changed files with 34 additions and 10 deletions

View File

@ -982,6 +982,34 @@ public:
}
static void checkAndRemoveNonDriverDiags(SmallVectorImpl<StoredDiagnostic> &
StoredDiagnostics) {
// Get rid of stored diagnostics except the ones from the driver which do not
// have a source location.
for (unsigned I = 0; I < StoredDiagnostics.size(); ++I) {
if (StoredDiagnostics[I].getLocation().isValid()) {
StoredDiagnostics.erase(StoredDiagnostics.begin()+I);
--I;
}
}
}
static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> &
StoredDiagnostics,
SourceManager &SM) {
// The stored diagnostic has the old source manager in it; update
// the locations to refer into the new source manager. Since we've
// been careful to make sure that the source manager's state
// before and after are identical, so that we can reuse the source
// location itself.
for (unsigned I = 0, N = StoredDiagnostics.size(); I < N; ++I) {
if (StoredDiagnostics[I].getLocation().isValid()) {
FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), SM);
StoredDiagnostics[I].setLocation(Loc);
}
}
}
/// Parse the source file into a translation unit using the given compiler
/// invocation, replacing the current translation unit.
///
@ -1052,7 +1080,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
CleanTemporaryFiles();
if (!OverrideMainBuffer) {
StoredDiagnostics.erase(stored_diag_afterDriver_begin(), stored_diag_end());
checkAndRemoveNonDriverDiags(StoredDiagnostics);
TopLevelDeclsInPreamble.clear();
}
@ -1080,13 +1108,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
// been careful to make sure that the source manager's state
// before and after are identical, so that we can reuse the source
// location itself.
for (unsigned I = NumStoredDiagnosticsFromDriver,
N = StoredDiagnostics.size();
I < N; ++I) {
FullSourceLoc Loc(StoredDiagnostics[I].getLocation(),
getSourceManager());
StoredDiagnostics[I].setLocation(Loc);
}
checkAndSanitizeDiags(StoredDiagnostics, getSourceManager());
// Keep track of the override buffer;
SavedMainFileBuffer = OverrideMainBuffer;
@ -1520,7 +1542,7 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
// Clear out old caches and data.
getDiagnostics().Reset();
ProcessWarningOptions(getDiagnostics(), Clang->getDiagnosticOpts());
StoredDiagnostics.erase(stored_diag_afterDriver_begin(), stored_diag_end());
checkAndRemoveNonDriverDiags(StoredDiagnostics);
TopLevelDecls.clear();
TopLevelDeclsInPreamble.clear();
@ -1563,7 +1585,7 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
PreambleDiagnostics.clear();
PreambleDiagnostics.insert(PreambleDiagnostics.end(),
stored_diag_afterDriver_begin(), stored_diag_end());
StoredDiagnostics.erase(stored_diag_afterDriver_begin(), stored_diag_end());
checkAndRemoveNonDriverDiags(StoredDiagnostics);
// Keep track of the preamble we precompiled.
setPreambleFile(this, FrontendOpts.OutputFile);
@ -2368,6 +2390,8 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column,
Act->Execute();
Act->EndSourceFile();
}
checkAndSanitizeDiags(StoredDiagnostics, getSourceManager());
}
CXSaveError ASTUnit::Save(StringRef File) {