diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 2ef609831637e..de0d32f68253a 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1011,6 +1011,9 @@ def : Flag<["-"], "Xcompiler">, IgnoredGCCCompat; def Z_Flag : Flag<["-"], "Z">, Group; def all__load : Flag<["-"], "all_load">; def allowable__client : Separate<["-"], "allowable_client">; +def allow_unrecognized_arguments : Flag<["--"], "allow-unrecognized-arguments">, + Visibility<[ClangOption, CLOption]>, + HelpText<"Ignore unrecognized command-line arguments instead of reporting an error.">; def ansi : Flag<["-", "--"], "ansi">, Group; def arch__errors__fatal : Flag<["-"], "arch_errors_fatal">; def arch : Separate<["-"], "arch">, Flags<[NoXarchOption,TargetSpecific]>; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 85a1335785542..4f2ac9ba8271c 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -303,29 +303,31 @@ InputArgList Driver::ParseArgStrings(ArrayRef ArgStrings, } } - for (const Arg *A : Args.filtered(options::OPT_UNKNOWN)) { - unsigned DiagID; - auto ArgString = A->getAsString(Args); - std::string Nearest; - if (getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) { - if (!IsCLMode() && - getOpts().findExact(ArgString, Nearest, - llvm::opt::Visibility(options::CC1Option))) { - DiagID = diag::err_drv_unknown_argument_with_suggestion; - Diags.Report(DiagID) << ArgString << "-Xclang " + Nearest; + if (!Args.hasArg(options::OPT_allow_unrecognized_arguments)) { + for (const Arg *A : Args.filtered(options::OPT_UNKNOWN)) { + unsigned DiagID; + auto ArgString = A->getAsString(Args); + std::string Nearest; + if (getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) { + if (!IsCLMode() && + getOpts().findExact(ArgString, Nearest, + llvm::opt::Visibility(options::CC1Option))) { + DiagID = diag::err_drv_unknown_argument_with_suggestion; + Diags.Report(DiagID) << ArgString << "-Xclang " + Nearest; + } else { + DiagID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl + : diag::err_drv_unknown_argument; + Diags.Report(DiagID) << ArgString; + } } else { - DiagID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl - : diag::err_drv_unknown_argument; - Diags.Report(DiagID) << ArgString; + DiagID = IsCLMode() + ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion + : diag::err_drv_unknown_argument_with_suggestion; + Diags.Report(DiagID) << ArgString << Nearest; } - } else { - DiagID = IsCLMode() - ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion - : diag::err_drv_unknown_argument_with_suggestion; - Diags.Report(DiagID) << ArgString << Nearest; + ContainsError |= Diags.getDiagnosticLevel(DiagID, SourceLocation()) > + DiagnosticsEngine::Warning; } - ContainsError |= Diags.getDiagnosticLevel(DiagID, SourceLocation()) > - DiagnosticsEngine::Warning; } for (const Arg *A : Args.filtered(options::OPT_o)) { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 422375240bab6..0ba29db471617 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -4991,15 +4991,17 @@ bool CompilerInvocation::CreateFromArgsImpl( Diags.Report(diag::err_drv_missing_argument) << Args.getArgString(MissingArgIndex) << MissingArgCount; - // Issue errors on unknown arguments. - for (const auto *A : Args.filtered(OPT_UNKNOWN)) { - auto ArgString = A->getAsString(Args); - std::string Nearest; - if (Opts.findNearest(ArgString, Nearest, VisibilityMask) > 1) - Diags.Report(diag::err_drv_unknown_argument) << ArgString; - else - Diags.Report(diag::err_drv_unknown_argument_with_suggestion) - << ArgString << Nearest; + if (!Args.hasArg(options::OPT_allow_unrecognized_arguments)) { + // Issue errors on unknown arguments. + for (const auto *A : Args.filtered(OPT_UNKNOWN)) { + auto ArgString = A->getAsString(Args); + std::string Nearest; + if (Opts.findNearest(ArgString, Nearest, VisibilityMask) > 1) + Diags.Report(diag::err_drv_unknown_argument) << ArgString; + else + Diags.Report(diag::err_drv_unknown_argument_with_suggestion) + << ArgString << Nearest; + } } ParseFileSystemArgs(Res.getFileSystemOpts(), Args, Diags); diff --git a/clang/test/Driver/unsupported-option.c b/clang/test/Driver/unsupported-option.c index 7234e52571582..465f1879b31c8 100644 --- a/clang/test/Driver/unsupported-option.c +++ b/clang/test/Driver/unsupported-option.c @@ -32,3 +32,7 @@ // RUN: not %clang -c -Qunused-arguments --target=aarch64-- -mfpu=crypto-neon-fp-armv8 %s 2>&1 \ // RUN: | FileCheck %s --check-prefix=QUNUSED_ARGUMENTS // QUNUSED_ARGUMENTS: error: unsupported option '-mfpu=' for target 'aarch64--' + +// RUN: %clang %s -invalid --allow-unrecognized-arguments -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=UNKNOWN_ARGUMENT +// UNKNOWN_ARGUMENT: warning: argument unused during compilation: '-invalid'