[cfe-dev] [Patch] Diagnose unused declaration
Douglas Gregor
dgregor at apple.com
Mon Jan 5 08:51:13 PST 2009
Hello,
On Jan 4, 2009, at 7:59 PM, EdB wrote:
> This time "used" informations are keep "on the side".
Thanks; that's much better.
> There is place for improvement but I want to be sure that
> information are at
> the right place before.
A few comments on this iteration:
static llvm::cl::opt<bool>
+WarnUnusedDeclaration("Wunused_declaration",
+ llvm::cl::desc("Warn for unused declaration"));
I suggest that we use the same command-line arguments as GCC, unless
there is some specific reason to deviate from them:
http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Warning-Options.html#Warning-Options
In Sema::PopDeclContext(), the warning-generation code needs to be
much more picky about which declarations it complains about. For
example, I tried this C++ example:
namespace N {
int x;
}
namespace N {
int f() {
return x;
}
}
and Clang produced 4 warnings: one each for x, f, __builtin_va_list,
and N:
This option should not produce warnings about any of these, because:
- x is the definition of a variable that can be referred to by other
translation units, so even if it isn't used within this translation
unit, we should not warn about it. Plus, "x" is used later on in the
program (in a different DeclContext for the namespace N). Note that
GCC's -Wunused-variable documentation explicitly says that it only
warns about local variables and non-constant static variables; we
should do something similar.
- f is the definition of a function, which could also be referenced
by other translation units. Note that GCC's -Wunused-function only
complains about static functions (and, presumably, functions in
anonymous namespaces) because those aren't visible outside of the
translation unit.
- __builtin_va_list wasn't written by the user, so we shouldn't
complain about it. Besides, do we even want to complain about unused
typedefs? Especially in C++, there are certainly reasons to write
typedefs even if they aren't used in the translation unit.
- N is a namespace; do we ever want to warn about those?
I see that UsedDeclaration grows throughout the processing of the
translation unit, because nothing is ever removed from the set (even
when it is no longer visible through name lookup). We'd like to avoid
that.
Does this warning work properly in C? In Sema::LookupDecl, it looks
like you need to change
for (; I != IdResolver.end(); ++I)
if ((*I)->getIdentifierNamespace() & NS)
return *I;
to
for (; I != IdResolver.end(); ++I)
if ((*I)->getIdentifierNamespace() & NS) {
UsedDeclaration.insert(*I);
return *I;
}
?
Also in Sema::LookupDecl:
- return MaybeConstructOverloadSet(Context, I, E);
+ Decl *D = MaybeConstructOverloadSet(Context, I, E);
+ UsedDeclaration.insert(static_cast<NamedDecl *>(D));
+ return D;
The result of MaybeConstructOverloadSet could be an
OverloadedFunctionDecl, which is transient and therefore should not be
inserted into the UsedDeclaration set (since we'd never know to remove
it).
Do we need the new code in ActOnEndOfTranslationUnit? It's nearly
identical to the new code in Sema::PopDeclContext, and translation
units are DeclContexts. Perhaps this code could be factored out?
Personally, I think that any patch introducing warnings for unused
variables/parameters/functions/etc. also needs to support GCC's
__attribute__((unused)) extension to turn off the warning for specific
declarations. We'll get a lot of complaints from GCC users if we
produce this warning when they've explicitly asked to suppress it for
a declaration.
You'll need to include a regression test that works with -verify along
with your patch, so that we can make sure this functionality doesn't
break in the future. You'll probably need at least two regression
tests, one each for C and C++. Try to exercise a bunch of different
language features in them, e.g., overloading in C++, uses of "extern",
"inline", etc. Getting this warning right is actually far harder than
it looks at first blush, but you've got a good start on it.
- Doug
More information about the cfe-dev
mailing list