This revision was automatically updated to reflect the committed changes. Closed by commit rGfd14a1f6fff3: [clang][Frontend] Add missing error handling (authored by LemonBoy, committed by dblaikie).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78658/new/ https://reviews.llvm.org/D78658 Files: clang/lib/Frontend/ASTUnit.cpp clang/unittests/Frontend/ASTUnitTest.cpp
Index: clang/unittests/Frontend/ASTUnitTest.cpp =================================================================== --- clang/unittests/Frontend/ASTUnitTest.cpp +++ clang/unittests/Frontend/ASTUnitTest.cpp @@ -150,4 +150,28 @@ &File->getFileEntry())); } +TEST_F(ASTUnitTest, LoadFromCommandLineEarlyError) { + EXPECT_FALSE( + llvm::sys::fs::createTemporaryFile("ast-unit", "c", FD, InputFileName)); + input_file = std::make_unique<ToolOutputFile>(InputFileName, FD); + input_file->os() << ""; + + const char *Args[] = {"clang", "-target", "foobar", InputFileName.c_str()}; + + auto Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions()); + auto PCHContainerOps = std::make_shared<PCHContainerOperations>(); + std::unique_ptr<clang::ASTUnit> ErrUnit; + + ASTUnit *AST = ASTUnit::LoadFromCommandLine( + &Args[0], &Args[4], PCHContainerOps, Diags, "", false, + CaptureDiagsKind::All, None, true, 0, TU_Complete, false, false, false, + SkipFunctionBodiesScope::None, false, true, false, false, None, &ErrUnit, + nullptr); + + ASSERT_EQ(AST, nullptr); + ASSERT_NE(ErrUnit, nullptr); + ASSERT_TRUE(Diags->hasErrorOccurred()); + ASSERT_NE(ErrUnit->stored_diag_size(), 0U); +} + } // anonymous namespace Index: clang/lib/Frontend/ASTUnit.cpp =================================================================== --- clang/lib/Frontend/ASTUnit.cpp +++ clang/lib/Frontend/ASTUnit.cpp @@ -69,6 +69,7 @@ #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" @@ -1118,6 +1119,19 @@ std::unique_ptr<CompilerInstance> Clang( new CompilerInstance(std::move(PCHContainerOps))); + // Clean up on error, disengage it if the function returns successfully. + auto CleanOnError = llvm::make_scope_exit([&]() { + // Remove the overridden buffer we used for the preamble. + SavedMainFileBuffer = nullptr; + + // Keep the ownership of the data in the ASTUnit because the client may + // want to see the diagnostics. + transferASTDataFromCompilerInstance(*Clang); + FailedParseDiagnostics.swap(StoredDiagnostics); + StoredDiagnostics.clear(); + NumStoredDiagnosticsFromDriver = 0; + }); + // Ensure that Clang has a FileManager with the right VFS, which may have // changed above in AddImplicitPreamble. If VFS is nullptr, rely on // createFileManager to create one. @@ -1200,7 +1214,7 @@ ActCleanup(Act.get()); if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) - goto error; + return true; if (SavedMainFileBuffer) TranslateStoredDiagnostics(getFileManager(), getSourceManager(), @@ -1210,7 +1224,7 @@ if (llvm::Error Err = Act->Execute()) { consumeError(std::move(Err)); // FIXME this drops errors on the floor. - goto error; + return true; } transferASTDataFromCompilerInstance(*Clang); @@ -1219,19 +1233,9 @@ FailedParseDiagnostics.clear(); - return false; + CleanOnError.release(); -error: - // Remove the overridden buffer we used for the preamble. - SavedMainFileBuffer = nullptr; - - // Keep the ownership of the data in the ASTUnit because the client may - // want to see the diagnostics. - transferASTDataFromCompilerInstance(*Clang); - FailedParseDiagnostics.swap(StoredDiagnostics); - StoredDiagnostics.clear(); - NumStoredDiagnosticsFromDriver = 0; - return true; + return false; } static std::pair<unsigned, unsigned>
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits