diff --git a/clang/test/Interpreter/fail.cpp b/clang/test/Interpreter/fail.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Interpreter/fail.cpp @@ -0,0 +1,17 @@ +// FIXME: There're some inconsistencies between interactive and non-interactive +// modes. For example, when clang-repl runs in the interactive mode, issues an +// error, and then successfully recovers if we decide it's a success then for +// the non-interactive mode the exit code should be a failure. +// RUN: clang-repl "int x = 10;" "int y=7; err;" "int y = 10;" +// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \ +// RUN: 'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix +// CHECK-DRIVER: i = 10 +// RUN: cat %s | not clang-repl | FileCheck %s +BOOM! +extern "C" int printf(const char *, ...); +int i = 42; +auto r1 = printf("i = %d\n", i); +// CHECK: i = 42 +%quit diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -50,7 +50,7 @@ // If we are running with -verify a reported has to be returned as unsuccess. // This is relevant especially for the test suite. -static int checkDiagErrors(const clang::CompilerInstance *CI) { +static int checkDiagErrors(const clang::CompilerInstance *CI, bool HasError) { unsigned Errs = CI->getDiagnostics().getClient()->getNumErrors(); if (CI->getDiagnosticOpts().VerifyDiagnostics) { // If there was an error that came from the verifier we must return 1 as @@ -62,7 +62,7 @@ // The interpreter expects BeginSourceFile/EndSourceFiles to be balanced. Client->BeginSourceFile(CI->getLangOpts(), &CI->getPreprocessor()); } - return Errs ? EXIT_FAILURE : EXIT_SUCCESS; + return (Errs || HasError) ? EXIT_FAILURE : EXIT_SUCCESS; } llvm::ExitOnError ExitOnErr; @@ -107,6 +107,8 @@ llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); } + bool HasError = false; + if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); // FIXME: Add LE.setListCompleter @@ -114,13 +116,17 @@ if (*Line == R"(%quit)") break; if (*Line == R"(%undo)") { - if (auto Err = Interp->Undo()) + if (auto Err = Interp->Undo()) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); + HasError = true; + } continue; } - if (auto Err = Interp->ParseAndExecute(*Line)) + if (auto Err = Interp->ParseAndExecute(*Line)) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); + HasError = true; + } } } @@ -129,5 +135,5 @@ // later errors use the default handling behavior instead. llvm::remove_fatal_error_handler(); - return checkDiagErrors(Interp->getCompilerInstance()); + return checkDiagErrors(Interp->getCompilerInstance(), HasError); }