aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-06-08 05:48:06 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-06-08 05:48:06 +0000
commit374a00bcc6e26b4fc3cd1d378a5d056c4c7d618e (patch)
tree29cc0165be6b097840462ccd0cd1a84f33513319
parentc18909ebd57608f8bec96dbd5e596c5695fa4045 (diff)
[libclang] Don't crash when saving a PCH from a prefix header
that does not exist. rdar://11607033 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158193 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Frontend/FrontendAction.h2
-rw-r--r--lib/Frontend/ASTUnit.cpp11
-rw-r--r--lib/Frontend/FrontendAction.cpp6
-rw-r--r--test/Index/pch-with-errors.c4
-rw-r--r--tools/libclang/CIndex.cpp2
5 files changed, 19 insertions, 6 deletions
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
index 6839028f97..c0056de5ca 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -188,7 +188,7 @@ public:
bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input);
/// Execute - Set the source managers main input file, and run the action.
- void Execute();
+ bool Execute();
/// EndSourceFile - Perform any per-file post processing, deallocate per-file
/// objects, and run statistics and output file cleanup code.
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index d6bdae4aaf..1ef5ba864e 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -1133,7 +1133,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
StoredDiagnostics);
}
- Act->Execute();
+ if (!Act->Execute())
+ goto error;
transferASTDataFromCompilerInstance(*Clang);
@@ -1795,7 +1796,13 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI,
AST->getCurrentTopLevelHashValue()));
Clang->setASTConsumer(new MultiplexConsumer(Consumers));
}
- Act->Execute();
+ if (!Act->Execute()) {
+ AST->transferASTDataFromCompilerInstance(*Clang);
+ if (OwnAST && ErrAST)
+ ErrAST->swap(OwnAST);
+
+ return 0;
+ }
// Steal the created target, context, and preprocessor.
AST->transferASTDataFromCompilerInstance(*Clang);
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index 1ff32921d9..fb53c71fa9 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -315,7 +315,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
return false;
}
-void FrontendAction::Execute() {
+bool FrontendAction::Execute() {
CompilerInstance &CI = getCompilerInstance();
// Initialize the main file entry. This needs to be delayed until after PCH
@@ -325,7 +325,7 @@ void FrontendAction::Execute() {
getCurrentInput().IsSystem
? SrcMgr::C_System
: SrcMgr::C_User))
- return;
+ return false;
}
if (CI.hasFrontendTimer()) {
@@ -333,6 +333,8 @@ void FrontendAction::Execute() {
ExecuteAction();
}
else ExecuteAction();
+
+ return true;
}
void FrontendAction::EndSourceFile() {
diff --git a/test/Index/pch-with-errors.c b/test/Index/pch-with-errors.c
index be8728eb72..2d396134e5 100644
--- a/test/Index/pch-with-errors.c
+++ b/test/Index/pch-with-errors.c
@@ -38,5 +38,7 @@ void foo(void) {
// CHECK-INDEX: [indexEntityReference]: kind: function | name: erroneous
// RUN: %clang -fsyntax-only %s -include %t.h 2>&1 | FileCheck -check-prefix=PCH-ERR %s
-
// PCH-ERR: error: PCH file contains compiler errors
+
+// RUN: c-index-test -write-pch %t.pch foobar.c 2>&1 | FileCheck -check-prefix=NONEXISTENT %s
+// NONEXISTENT: Unable to load translation unit
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index a508b772e5..8eaf4ecf0c 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -2692,6 +2692,8 @@ int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+ if (!CXXUnit->hasSema())
+ return CXSaveError_InvalidTU;
SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };