From 374a00bcc6e26b4fc3cd1d378a5d056c4c7d618e Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Fri, 8 Jun 2012 05:48:06 +0000 Subject: [PATCH] [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 --- include/clang/Frontend/FrontendAction.h | 2 +- lib/Frontend/ASTUnit.cpp | 11 +++++++++-- lib/Frontend/FrontendAction.cpp | 6 ++++-- test/Index/pch-with-errors.c | 4 +++- tools/libclang/CIndex.cpp | 2 ++ 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(TU->TUData); ASTUnit::ConcurrencyCheck Check(*CXXUnit); + if (!CXXUnit->hasSema()) + return CXSaveError_InvalidTU; SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None }; -- 2.40.0