diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -212,6 +212,10 @@ Trivial automatic variable initialization to zero is only here for benchmarks, it'll eventually be removed, and I'm OK with that because I'm only using it to benchmark +.. option:: --end-no-unused-arguments + +Start emitting warnings for unused driver arguments + .. option:: -exported\_symbols\_list .. option:: -faligned-new= @@ -663,6 +667,10 @@ .. option:: -single\_module +.. option:: --start-no-unused-arguments + +Don't emit warnings about unused arguments for the following arguments + .. option:: -static-libgcc .. option:: -static-libsan diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1076,6 +1076,8 @@ def emit_merged_ifs : Flag<["-"], "emit-merged-ifs">, Flags<[CC1Option]>, Group, HelpText<"Generate Interface Stub Files, emit merged text not binary.">; +def end_no_unused_arguments : Flag<["--"], "end-no-unused-arguments">, Flags<[CoreOption]>, + HelpText<"Start emitting warnings for unused driver arguments">; def interface_stub_version_EQ : JoinedOrSeparate<["-"], "interface-stub-version=">, Flags<[CC1Option]>; def exported__symbols__list : Separate<["-"], "exported_symbols_list">; def e : JoinedOrSeparate<["-"], "e">, Flags<[LinkerInput]>, Group; @@ -3913,6 +3915,8 @@ def single__module : Flag<["-"], "single_module">; def specs_EQ : Joined<["-", "--"], "specs=">, Group; def specs : Separate<["-", "--"], "specs">, Flags<[Unsupported]>; +def start_no_unused_arguments : Flag<["--"], "start-no-unused-arguments">, Flags<[CoreOption]>, + HelpText<"Don't emit warnings about unused arguments for the following arguments">; def static_libgcc : Flag<["-"], "static-libgcc">; def static_libstdcxx : Flag<["-"], "static-libstdc++">; def static : Flag<["-", "--"], "static">, Group, Flags<[NoArgumentUnused]>; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -367,7 +367,20 @@ bool HasNostdlib = Args.hasArg(options::OPT_nostdlib); bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx); bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs); + bool IgnoreUnused = false; for (Arg *A : Args) { + if (IgnoreUnused) + A->claim(); + + if (A->getOption().matches(options::OPT_start_no_unused_arguments)) { + IgnoreUnused = true; + continue; + } + if (A->getOption().matches(options::OPT_end_no_unused_arguments)) { + IgnoreUnused = false; + continue; + } + // Unfortunately, we have to parse some forwarding options (-Xassembler, // -Xlinker, -Xpreprocessor) because we either integrate their functionality // (assembler and preprocessor), or bypass a previous driver ('collect2'). diff --git a/clang/test/Driver/diagnostics.c b/clang/test/Driver/diagnostics.c --- a/clang/test/Driver/diagnostics.c +++ b/clang/test/Driver/diagnostics.c @@ -1,9 +1,53 @@ // Parse diagnostic arguments in the driver -// PR12181 -// RUN: not %clang -target x86_64-apple-darwin10 \ -// RUN: -fsyntax-only -fzyzzybalubah \ -// RUN: -Werror=unused-command-line-argument %s +// Exactly which arguments are warned about and which aren't differ based +// on what target is selected. -stdlib= and -fuse-ld= emit diagnostics when +// compiling C code, for e.g. *-linux-gnu. Linker inputs, like -lfoo, emit +// diagnostics when only compiling for all targets. -// RUN: not %clang -target x86_64-apple-darwin10 \ -// RUN: -fsyntax-only -fzyzzybalubah -Werror %s +// This is normally a non-fatal warning: +// RUN: %clang --target=x86_64-apple-darwin10 \ +// RUN: -fsyntax-only -lfoo %s 2>&1 | FileCheck %s + +// Either with a specific -Werror=unused.. or a blanket -Werror, this +// causes the command to fail. +// RUN: not %clang --target=x86_64-apple-darwin10 \ +// RUN: -fsyntax-only -lfoo \ +// RUN: -Werror=unused-command-line-argument %s 2>&1 | FileCheck %s + +// RUN: not %clang --target=x86_64-apple-darwin10 \ +// RUN: -fsyntax-only -lfoo -Werror %s 2>&1 | FileCheck %s + +// With a specific -Wno-..., no diagnostic should be printed. +// RUN: %clang --target=x86_64-apple-darwin10 \ +// RUN: -fsyntax-only -lfoo -Werror \ +// RUN: -Wno-unused-command-line-argument %s 2>&1 | count 0 + +// With -Qunused-arguments, no diagnostic should be printed. +// RUN: %clang --target=x86_64-apple-darwin10 \ +// RUN: -fsyntax-only -lfoo -Werror \ +// RUN: -Qunused-arguments %s 2>&1 | count 0 + +// With the argument enclosed in --{start,end}-no-unused-arguments, +// there's no diagnostic. +// RUN: %clang --target=x86_64-apple-darwin10 -fsyntax-only \ +// RUN: --start-no-unused-arguments -lfoo --end-no-unused-arguments \ +// RUN: -Werror %s 2>&1 | count 0 + +// With --{start,end}-no-unused-argument around a different argument, it +// still warns about the unused argument. +// RUN: not %clang --target=x86_64-apple-darwin10 \ +// RUN: --start-no-unused-arguments -fsyntax-only --end-no-unused-arguments \ +// RUN: -lfoo -Werror %s 2>&1 | FileCheck %s + +// Test clang-cl warning about unused linker options. +// RUN: not %clang_cl -fsyntax-only /WX %s \ +// RUN: -link 2>&1 | FileCheck %s --check-prefix=CL-WARNING + +// Test clang-cl ignoring the warning with --start-no-unused-arguments. +// RUN: %clang_cl -fsyntax-only /WX %s \ +// RUN: --start-no-unused-arguments -link --end-no-unused-arguments 2>&1 | count 0 + +// CHECK: -lfoo: 'linker' input unused + +// CL-WARNING: argument unused during compilation: '-link'