From d851833c9a76c267824cd58c155dd660546f59b1 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari <ehsan.akhgari@gmail.com> Date: Mon, 25 Jan 2016 21:14:52 +0000 Subject: [PATCH] [MSVC Compat] Only warn for unknown clang-cl arguments Summary: MSVC's driver accepts all unknown arguments but warns about them. clang by default rejects all unknown arguments. This causes issues specifically with build systems such as autoconf which liberally pass things such as $LDFLAGS to the compiler and expect everything to work. This patch teaches clang-cl to ignore unknown driver arguments. Reviewers: rnk Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D16511 llvm-svn: 258720 --- clang/docs/UsersManual.rst | 5 +++-- .../include/clang/Basic/DiagnosticDriverKinds.td | 3 +++ clang/include/clang/Basic/DiagnosticGroups.td | 2 ++ clang/lib/Driver/Driver.cpp | 11 ++++++++--- clang/lib/Driver/Tools.cpp | 4 ++++ clang/test/Driver/cl-fallback.c | 3 +++ clang/test/Driver/unknown-arg.c | 15 +++++++++++++++ clang/test/Misc/serialized-diags-driver.c | 4 ++-- 8 files changed, 40 insertions(+), 7 deletions(-) diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index ea75d1e2227a..32c6ac2270fe 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -2024,8 +2024,9 @@ with a warning. For example: To suppress warnings about unused arguments, use the ``-Qunused-arguments`` option. -Options that are not known to clang-cl will cause errors. If they are spelled with a -leading ``/``, they will be mistaken for a filename: +Options that are not known to clang-cl will be ignored by default. Use the +``-Werror=unknown-argument`` option in order to treat them as errors. If these +options are spelled with a leading ``/``, they will be mistaken for a filename: :: diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index b04498f3188c..1ba9e1464cdd 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -93,6 +93,9 @@ def err_target_unsupported_arch def err_drv_I_dash_not_supported : Error< "'%0' not supported, please use -iquote instead">; def err_drv_unknown_argument : Error<"unknown argument: '%0'">; +def warn_drv_unknown_argument_clang_cl : Warning< + "unknown argument ignored in clang-cl: '%0'">, + InGroup<UnknownArgument>; def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">; def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">; def err_drv_invalid_remap_file : Error< diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 41e7d2a85e1d..969050df5963 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -848,3 +848,5 @@ def FutureCompat : DiagGroup<"future-compat">; def InvalidOrNonExistentDirectory : DiagGroup<"invalid-or-nonexistent-directory">; def OptionIgnored : DiagGroup<"option-ignored">; + +def UnknownArgument : DiagGroup<"unknown-argument">; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 5c01ef0bba7c..22eed5cab6f7 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -146,7 +146,9 @@ InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings) { } for (const Arg *A : Args.filtered(options::OPT_UNKNOWN)) - Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(Args); + Diags.Report(IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl : + diag::err_drv_unknown_argument) + << A->getAsString(Args); return Args; } @@ -1710,8 +1712,11 @@ void Driver::BuildJobs(Compilation &C) const { continue; } - Diag(clang::diag::warn_drv_unused_argument) - << A->getAsString(C.getArgs()); + // In clang-cl, don't mention unknown arguments here since they have + // already been warned about. + if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) + Diag(clang::diag::warn_drv_unused_argument) + << A->getAsString(C.getArgs()); } } } diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 2bbcb275a4b8..814eb353c5ce 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -9708,6 +9708,10 @@ std::unique_ptr<Command> visualstudio::Compiler::GetCommand( options::OPT__SLASH_MT, options::OPT__SLASH_MTd)) A->render(Args, CmdArgs); + // Pass through all unknown arguments so that the fallback command can see + // them too. + Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN); + // Input filename. assert(Inputs.size() == 1); const InputInfo &II = Inputs[0]; diff --git a/clang/test/Driver/cl-fallback.c b/clang/test/Driver/cl-fallback.c index e5ebde5c0182..f788e4cab162 100644 --- a/clang/test/Driver/cl-fallback.c +++ b/clang/test/Driver/cl-fallback.c @@ -3,6 +3,7 @@ // RUN: %clang_cl --target=i686-pc-win32 /fallback /Dfoo=bar /Ubaz /Ifoo /O0 /Ox /GR /GR- /Gy /Gy- \ // RUN: /Gw /Gw- /LD /LDd /EHs /EHs- /Zl /MD /MDd /MTd /MT /FImyheader.h /Zi \ +// RUN: -garbage -moregarbage \ // RUN: -### -- %s 2>&1 \ // RUN: | FileCheck %s // CHECK: "-fdiagnostics-format" "msvc-fallback" @@ -31,6 +32,8 @@ // CHECK: "/EHs-" // CHECK: "/Zl" // CHECK: "/MT" +// CHECK: "-garbage" +// CHECK: "-moregarbage" // CHECK: "/Tc" "{{.*cl-fallback.c}}" // CHECK: "/Fo{{.*cl-fallback.*.obj}}" diff --git a/clang/test/Driver/unknown-arg.c b/clang/test/Driver/unknown-arg.c index f834a0e8db92..09889bf1a879 100644 --- a/clang/test/Driver/unknown-arg.c +++ b/clang/test/Driver/unknown-arg.c @@ -1,5 +1,11 @@ // RUN: not %clang %s -cake-is-lie -%0 -%d -HHHH -munknown-to-clang-option -print-stats -funknown-to-clang-option 2>&1 | \ // RUN: FileCheck %s +// RUN: %clang_cl -cake-is-lie -%0 -%d -HHHH -munknown-to-clang-option -print-stats -funknown-to-clang-option -c -- %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CL +// RUN: not %clang_cl -cake-is-lie -%0 -%d -HHHH -munknown-to-clang-option -print-stats -funknown-to-clang-option -c -Werror=unknown-argument -- %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CL +// RUN: %clang_cl -cake-is-lie -%0 -%d -HHHH -munknown-to-clang-option -print-stats -funknown-to-clang-option -c -Wno-unknown-argument -- %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=SILENT --allow-empty // CHECK: unknown argument: '-cake-is-lie' // CHECK: unknown argument: '-%0' @@ -8,6 +14,15 @@ // CHECK: unknown argument: '-munknown-to-clang-option' // CHECK: unknown argument: '-print-stats' // CHECK: unknown argument: '-funknown-to-clang-option' +// CL: unknown argument ignored in clang-cl: '-cake-is-lie' +// CL: unknown argument ignored in clang-cl: '-%0' +// CL: unknown argument ignored in clang-cl: '-%d' +// CL: unknown argument ignored in clang-cl: '-HHHH' +// CL: unknown argument ignored in clang-cl: '-munknown-to-clang-option' +// CL: unknown argument ignored in clang-cl: '-print-stats' +// CL: unknown argument ignored in clang-cl: '-funknown-to-clang-option' +// SILENT-NOT: error +// SILENT-NOT: warning // RUN: %clang -S %s -o %t.s -Wunknown-to-clang-option 2>&1 | FileCheck --check-prefix=IGNORED %s diff --git a/clang/test/Misc/serialized-diags-driver.c b/clang/test/Misc/serialized-diags-driver.c index ad07d666c8c1..617ac8c6ef92 100644 --- a/clang/test/Misc/serialized-diags-driver.c +++ b/clang/test/Misc/serialized-diags-driver.c @@ -5,10 +5,10 @@ // doesn't litter the user's system with preprocessed output. // RUN: rm -f %t -// RUN: %clang -Wx-unknown-warning -Wall -fsyntax-only --serialize-diagnostics %t.diag %s +// RUN: %clang -Wx-typoed-warning -Wall -fsyntax-only --serialize-diagnostics %t.diag %s // RUN: c-index-test -read-diagnostics %t.diag 2>&1 | FileCheck %s -// CHECK: warning: unknown warning option '-Wx-unknown-warning' [-Wunknown-warning-option] [] +// CHECK: warning: unknown warning option '-Wx-typoed-warning' [-Wunknown-warning-option] [] // CHECK: warning: variable 'voodoo' is uninitialized when used here [-Wuninitialized] // CHECK: note: initialize the variable 'voodoo' to silence this warning []