[cfe-commits] Clang change to detect and warn about unused private members
Chandler Carruth
chandlerc at google.com
Wed Feb 1 10:52:25 PST 2012
Thanks, comments inline... This is sadly a pretty cursory read, sorry,
working on other stuff. I think, especially given the "used" concept at
play here, Richard or Eli looking at this would be very good. =] Thanks
again for working on it.
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -134,6 +134,9 @@ def warn_unneeded_member_function : Warning<
"member function %0 is not needed and will not be emitted">,
InGroup<UnneededMemberFunction>, DefaultIgnore;
+def warn_unused_private_field: Warning<"private field %0 is not used">,
+ InGroup<UnusedPrivateField>, DefaultIgnore;
+
I wouldn't separate this in its own group w/ vertical whitespace, but
rather jam it in with the other unused warning messages.
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1617,8 +1617,25 @@ Sema::ActOnCXXMemberDeclarator(Scope *S,
AccessSpecifier AS, Declarator &D,
assert((Name || isInstField) && "No identifier for non-field ?");
- if (isInstField)
- FieldCollector->Add(cast<FieldDecl>(Member));
+ if (isInstField) {
+ FieldDecl *FD = cast<FieldDecl>(Member);
+ FieldCollector->Add(FD);
+ if (FD->getAccess() == AS_private) {
+ bool hasNoSideEffects = true;
+ if (!FD->getType().isNull()) {
+ if (const CXXRecordDecl *RD =
+ FD->getType().getTypePtrOrNull()->getAsCXXRecordDecl()) {
You shouldn't need getTypePtrOrNull() here. QualType provides an ->
overload that delegates to Type.
+ if
(!FD->getParent()->getTypeForDecl()->isInstantiationDependentType() &&
+ hasNoSideEffects)
I'm a bit surprised at checking InstantiationDependentType here... Not just
Dependent... Also some comments as to what this is supposed to handle would
be good...
@@ -2063,6 +2080,15 @@ Sema::BuildMemberInitializer(ValueDecl *Member,
assert((DirectMember || IndirectMember) &&
"Member must be a FieldDecl or IndirectFieldDecl");
+ // FIXME: Allow more initializers not to count as usage, e.g. where all
+ // arguments are primitive types.
+ ValueDecl *VD = dyn_cast<ValueDecl>(Member);
If you know the cast will always succeed, just use "cast" rather than
"dyn_cast".
+ if (!VD->getType()->isBuiltinType() &&
+ !VD->getType()->isAnyPointerType() &&
Why are these here? We already have constraints on the type of things above
when we check the Field Decl? Maybe I just don't understand what these are
doing.
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1791,6 +1791,19 @@ Sema::InstantiateClass(SourceLocation
PointOfInstantiation,
if (OldField->getInClassInitializer())
FieldsWithMemberInitializers.push_back(std::make_pair(OldField,
Field));
+ if (Field->getAccess() == AS_private) {
+ bool hasNoSideEffects = true;
+ if (!Field->getType().isNull()) {
+ if (const CXXRecordDecl *RD =
+ Field->getType().getTypePtrOrNull()->getAsCXXRecordDecl())
{
+ hasNoSideEffects = RD->isCompleteDefinition() &&
+ RD->hasTrivialDefaultConstructor() &&
+ RD->hasTrivialDestructor();
+ }
+ }
+ if (hasNoSideEffects)
+ UnusedPrivateFields.insert(Field);
+ }
This is the second copy of this pattern. We should either have template
instantiation call the not-template Sema routines to do this, or we should
factor the predicate into a helper somewhere, likely FieldDecl.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120201/dda3ba39/attachment.html>
More information about the cfe-commits
mailing list