-Wunused-* where macros declare multiple things

While evaluating the viability of Clang's -Wunused-* warnings
(specifically -Wunused-variable, -Wunused-function, and
-Wunused-member-function*) we've run in to some fairly noisy but
common idioms involving macros.

Most obviously about 30% of -Wunused-member-function warnings came
from uses of GMock. When defining a mocking member, GMock's macros
define two member functions (one being, commonly, the function
overriding the function to mock) and a member variable. In a
reasonable number of cases the second member function (the one used to
set expectations) is not called.

While not being deeply familiar with gmock, I believe this is a
reasonably valid use case & would cause the test to fail should that
member function ever be called (essentially an implicit expectation of
"never call").

(I've seen a smaller number of cases of -Wunused-function/variable due
to non-gmock but similar macros that define multiple things some of
which are used/important)

In the interests of making this warning viable for use in such a
codebase, I'm considering a few of options:

1) ignore any -Wunused-* when the thing being ignored is written inside a macro
2) build up a mapping of SourceLocation to a flag about whether any
declaration at that SourceLocation is externally used (this seems
expensive to me, but might still be viable)
3) fix the code by adding 'unused' attributes to all the
functions/variables defined in any such macros

Any other thoughts/ideas about how these sort of issues might be
addressed? Preferences of the available options?

* see, for example, the recent cfe-dev thread on the issues of
mangling/linkage in unnamed but instantiated classes nested inside
classes with external linkage

+1. I was going to write just such a patch for -Wunused-value; macros
are the only significant source of false positives I've seen for this
warning.

-Matt

Agreed (fwiw I got a buildbreak in gdb because of this - a legit macro
that was just trying to evaluate to 'true', essentially: #define
FOO(bar) (fun(bar), true) )

Though I don't think the solution to unused file scoped decls will be
immediately applicable to -Wunused-value.

Attached is a trivial, possibly hackish, solution to unused file
scoped decls. If anyone feels like there's an important collection of
true positives this suppresses or has other concerns about such a
simplistic approach, I'd love to hear about it.

Thanks,
- David

unused.diff (903 Bytes)