diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -84,6 +84,10 @@ static InputKind ParseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args, clang::DiagnosticsEngine &diags) { + + // By default the frontend driver creates a ParseSyntaxOnly action. + opts.programAction_ = ParseSyntaxOnly; + // Identify the action (i.e. opts.ProgramAction) if (const llvm::opt::Arg *a = args.getLastArg(clang::driver::options::OPT_Action_Group)) { diff --git a/flang/lib/Frontend/FrontendAction.cpp b/flang/lib/Frontend/FrontendAction.cpp --- a/flang/lib/Frontend/FrontendAction.cpp +++ b/flang/lib/Frontend/FrontendAction.cpp @@ -11,7 +11,9 @@ #include "flang/Frontend/FrontendActions.h" #include "flang/Frontend/FrontendOptions.h" #include "flang/FrontendTool/Utils.h" +#include "clang/Basic/DiagnosticFrontend.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/VirtualFileSystem.h" using namespace Fortran::frontend; @@ -31,6 +33,30 @@ CompilerInstance &ci, const FrontendInputFile &realInput) { FrontendInputFile input(realInput); + + // Return immediately if the input file does not exist or is not a file. Note + // that we cannot check this for input from stdin. + if (input.file() != "-") { + if (!llvm::sys::fs::is_regular_file(input.file())) { + // Create an diagnostic ID to report + unsigned diagID; + if (llvm::vfs::getRealFileSystem()->exists(input.file())) { + ci.diagnostics().Report(clang::diag::err_fe_error_reading) + << input.file(); + diagID = ci.diagnostics().getCustomDiagID( + clang::DiagnosticsEngine::Error, "%0 is not a regular file"); + } else { + diagID = ci.diagnostics().getCustomDiagID( + clang::DiagnosticsEngine::Error, "%0 does not exist"); + } + + // Report the diagnostic and return + ci.diagnostics().Report(diagID) << input.file(); + BeginSourceFileCleanUp(*this, ci); + return false; + } + } + assert(!instance_ && "Already processing a source file!"); assert(!realInput.IsEmpty() && "Unexpected empty filename!"); set_currentInput(realInput); diff --git a/flang/test/Flang-Driver/missing-input.f90 b/flang/test/Flang-Driver/missing-input.f90 --- a/flang/test/Flang-Driver/missing-input.f90 +++ b/flang/test/Flang-Driver/missing-input.f90 @@ -1,5 +1,31 @@ -! RUN: not %flang-new 2>&1 | FileCheck %s - ! REQUIRES: new-flang-driver -! CHECK: flang-new: error: no input files +! Test the behaviour of the driver when input is missing or is invalid. Note +! that with the compiler driver (flang-new), the input _has_ to be specified. +! Indeed, the driver decides what "job/command" to create based on the input +! file's extension. No input file means that it doesn't know what to do +! (compile? preprocess? link?). The frontend driver (flang-new -fc1) simply +! assumes that "no explicit input == read from stdin" + +!-------------------------- +! FLANG DRIVER (flang-new) +!-------------------------- +! RUN: not %flang-new 2>&1 | FileCheck %s --check-prefix=FLANG-NO-FILE +! RUN: not %flang-new %t 2>&1 | FileCheck %s --check-prefix=FLANG-NONEXISTENT-FILE + +!----------------------------------------- +! FLANG FRONTEND DRIVER (flang-new -fc1) +!----------------------------------------- +! RUN: not %flang-new -fc1 %t 2>&1 | FileCheck %s --check-prefix=FLANG-FC1-NONEXISTENT-FILE +! RUN: not %flang-new -fc1 %S 2>&1 | FileCheck %s --check-prefix=FLANG-FC1-DIR + +!----------------------- +! EXPECTED OUTPUT +!----------------------- +! FLANG-NO-FILE: flang-new: error: no input files + +! FLANG-NONEXISTENT-FILE: flang-new: error: no such file or directory: {{.*}} +! FLANG-NONEXISTENT-FILE: flang-new: error: no input files + +! FLANG-FC1-NONEXISTENT-FILE: error: {{.*}} does not exist +! FLANG-FC1-DIR: error: {{.*}} is not a regular file