Clang -Wunused-command-line-argument
2023-8-25 15:0:0 Author: maskray.me(查看原文) 阅读量:24 收藏

clangDriver is the library implementing the compiler driver for Clang. It utilitizes LLVMOption to process command line options. As options are processed when required, as opposed to use a large switch, Clang gets the ability to detect unused options straightforwardly.

When an option is checked with APIs such as hasArg and getLastArg, its "claimed" bit is set.

1
2
3
4
5
6
7
8
9
template<typename ...OptSpecifiers>
Arg *getLastArg(OptSpecifiers ...Ids) const {
Arg *Res = nullptr;
for (Arg *A : filtered(Ids...)) {
Res = A;
Res->claim();
}
return Res;
}

After all options are processed, Clang reports a -Wunused-command-line-argument diagnostic for each unclaimed option. There are multiple possible messages, but argument unused during compilation is the most common one.

1
2
3
4
5
6
7
8
% clang -c -ftime-trace a.s
clang: warning: argument unused during compilation: '-ftime-trace' [-Wunused-command-line-argument]
% clang -c a.c -la
clang: warning: -la: 'linker' input unused [-Wunused-command-line-argument]
% clang -c -ftime-trace -Werror a.s
clang: error: argument unused during compilation: '-ftime-trace' [-Werror,-Wunused-command-line-argument]
% clang -c -ftime-trace -Werror=unused-command-line-argument a.s
clang: error: argument unused during compilation: '-ftime-trace' [-Werror,-Wunused-command-line-argument]

There are many heuristics to enhance the desirability of -Wunused-command-line-argument, which can be rather subjective. For instance, options that are relevant only during compilation do not result in -Wunused-command-line-argument diagnostics when linking is performed. This is necessary to support linking actions that utilitize CFLAGS or CXXFLAGS.

1
% clang -faddrsig -fpic -march=generic a.o

Default options

There is a tension between -Wunused-command-line-argument and default options. Let's consider a scenario where we specify --rtlib=compiler-rt --unwindlib=libunwind in CFLAGS and CXXFLAGS to utilize compiler-rt and LLVM libunwind. ClangDriver claims --rtlib and --unwindlib in the following code snippet:

1
2
3
4
5
6
7
8
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_r)) {
if (!Args.hasArg(options::OPT_nodefaultlibs)) {

}
if (!Args.hasArg(options::OPT_nostartfiles)) {

}
}

However, if a build target employs -nostdlib or -nodefaultlibs, options such as --rtlib, --unwindlib, and many other linker options (e.g. -static-libstdc++ and -pthread) will not be claimed, resulting in unused argument diagnostics:

1
2
3
4
5
% clang --rtlib=compiler-rt --unwindlib=libunwind -stdlib=libstdc++ -static-libstdc++ -pthread -nostdlib a.o
clang: warning: argument unused during compilation: '--rtlib=compiler-rt' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '--unwindlib=libunwind' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-static-libstdc++' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-pthread' [-Wunused-command-line-argument]

While some options like -stdlib= do not trigger a diagnostic, this seems more like a happenstance rather than a deliberate design choice.

To suppress the diagnostics, we can utilitize --start-no-unused-arguments and --end-no-unused-arguments (Clang 14) like the following:

1
% clang --start-no-unused-arguments --rtlib=compiler-rt --unwindlib=libunwind -stdlib=libstdc++ -static-libstdc++ -pthread --end-no-unused-arguments -nostdlib a.o

There is also a heavy hammer -Qunused-arguments to suppress -Wunused-command-line-argument diagnostics regardless of options' positions:

1
% clang -Qunused-arguments --rtlib=compiler-rt --unwindlib=libunwind -stdlib=libstdc++ -static-libstdc++ -pthread -nostdlib a.o

Conveniently, options specified in a Clang configuration file are automatically claimed.

1
2
3
4
5
6
7
8
9
10
11
cat >a.cfg <<e
-stdlib=libstdc++
--rtlib=libgcc
--unwindlib=libgcc
e
clang --config=./a.cfg a.c
mkdir bin lib
ln -s /usr/bin/clang bin/
cp a.cfg bin/clang.cfg
ln -s /usr/lib/clang lib/
bin/clang -no-canonical-prefixes a.c

In the last command, I specify -no-canonical-prefixes so that clang will find dirname(clang)/clang.cfg, otherwise Clang would try to find dirname(realname(clang))/clang.cfg.


文章来源: https://maskray.me/blog/2023-08-25-clang-wunused-command-line-argument
如有侵权请联系:admin#unsafe.sh